LeetCode C++ 将 char[] 转换为字符串,抛出 AddressSanitizer: stack-buffer-overflow 错误

LeetCode C++ Convert char[] to string, throws AddressSanitizer: stack-buffer-overflow error

我正在学习 C++,在 LeetCode 上,将 char[] 转换为 string 会出现 AddressSanitizer: stack-buffer-overflow 错误。

string test1() /* Line 70 */
{
    char test[] = "11";
    return string(test);
}

string test2() /* Line 76 */
{
    char test[] = {'1', '1'};
    return string(test);
}

int main()
{
    cout << test1() << endl;
    cout << test2() << endl;
}

在上面的代码中,test1 returns "11" 和 test2 在 ASAN 开启的情况下给出了以下错误。为什么会这样?它们不只是初始化字符数组的不同方式吗?

==87465==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffee2400c22 at pc 0x00010d837634 bp 0x7ffee2400ad0 sp 0x7ffee2400290
READ of size 3 at 0x7ffee2400c22 thread T0
pc_0x10d837633###func_wrap_strlen###file_<null>###line_3###obj_(libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1a633)
pc_0x10d803a14###func_std::__1::char_traits<char>::length(char const*)###file___string###line_253###obj_(CCC:x86_64+0x100005a14)
pc_0x10d803950###func_std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*)###file_string###line_819###obj_(CCC:x86_64+0x100005950)
pc_0x10d80326c###func_std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<std::nullptr_t>(char const*)###file_string###line_817###obj_(CCC:x86_64+0x10000526c)
pc_0x10d80338f###func_test2()###file_p67-add-binary.cpp###line_79###obj_(CCC:x86_64+0x10000538f)
pc_0x10d803569###func_main###file_p67-add-binary.cpp###line_85###obj_(CCC:x86_64+0x100005569)
pc_0x7fff6cf80cc8###func_start###file_<null>###line_2###obj_(libdyld.dylib:x86_64+0x1acc8)
Address 0x7ffee2400c22 is located in stack of thread T0 at offset 34 in frame
pc_0x10d80328f###func_test2()###file_p67-add-binary.cpp###line_77###obj_(CCC:x86_64+0x10000528f)
  This frame has 1 object(s):
    [32, 34) 'test' (line 78) <== Memory access at offset 34 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x1a633) in wrap_strlen+0x183
Shadow bytes around the buggy address:
  0x1fffdc480130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffdc480140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffdc480150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffdc480160: f1 f1 f1 f1 f8 f2 f8 f3 00 00 00 00 00 00 00 00
  0x1fffdc480170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1fffdc480180: f1 f1 f1 f1[02]f3 f3 f3 00 00 00 00 00 00 00 00
  0x1fffdc480190: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
  0x1fffdc4801a0: f8 f8 f8 f2 f2 f2 f2 f2 00 00 00 f3 f3 f3 f3 f3
  0x1fffdc4801b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffdc4801c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1fffdc4801d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc

如果您希望 char * 作为字符串正确处理,您必须确保它以 null 结尾:

char test[] {'1', '1', '[=10=]'};

字符串文字会自动执行此操作。 "11" 等同于 {'1', '1', '[=14=]'}.


或者,您可以传递要读取的字符数:

string str(test, sizeof test);