類似于LeetCode C Convert char[] to string, throws AddressSanitizer: stack-buffer-overflow 錯誤
代碼是
#include <string>
int main() {
char buf[10] = {6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
std::string s{buf, 2, 3};
return 0;
}
執行以地址消毒劑抱怨strlen's 結束stack-buffer-overflow:
$ clang -g -fsanitize=address foo.cpp ; ./a.out
=================================================================
==1001715==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd76b2510a at pc 0x00000042f029 bp 0x7ffd76b250b0 sp 0x7ffd76b24870
READ of size 23 at 0x7ffd76b2510a thread T0
#0 0x42f028 in strlen (/tmp/a.out 0x42f028)
#1 0x7fd6de786e9b in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (/usr/lib/x86_64-linux-gnu/libstdc .so.6 0x145e9b)
#2 0x4c6cfe in main /tmp/foo.cpp:6:19
#3 0x7fd6de2d60b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
#4 0x41c3fd in _start (/tmp/a.out 0x41c3fd)
我希望std::string s{buf, 2, 3};呼叫具有已知邊界的建構式多載(從 2 開始,長度為 3)。為什么叫strlen()?使用哪種多載?
uj5u.com熱心網友回復:
檢查 cpp 見解。這是查看多載決議期間使用的內容的好工具。
它生成這個:
#include <string>
int main()
{
char buf[10] = {6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
std::string s = std::basic_string<char, std::char_traits<char>, std::allocator<char> >{std::basic_string<char, std::char_traits<char>, std::allocator<char> >(buf, std::allocator<char>()), 2, 3};
return 0;
}
清理后使其更具可讀性:
#include <string>
int main()
{
char buf[10] = {6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
std::string s = std::string{std::string(buf), 2, 3};
return 0;
}
因此請注意,buf首先轉換為std::string并且此轉換需要strlen. 由于您的陣列不包含終止零緩沖區溢位發生。
uj5u.com熱心網友回復:
HolyBlackCat 的回答和 Marek R 的回答解釋了為什么它是錯誤的。這是使用 (pointer, count) 建構式的解決方案:
std::string s{buf 2, 3};
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/404673.html
標籤:
上一篇:用換行符列印但沒有空格
下一篇:c 回圈沒有輸出
