代码之家  ›  专栏  ›  技术社区  ›  Bishnu Chalise

cout导致char指针的打印地址内存泄漏?

  •  1
  • Bishnu Chalise  · 技术社区  · 2 年前

    我有一个非常基本的程序来打印指向char的指针地址,但当我运行这段代码时,它会导致内存泄漏。

    我正在使用 termux on android 装置我用来运行文件的命令是 g++ -Wall -Wextra -fsanitize=address -o out filename.cpp && ./out

    #include <iostream>
    using namespace std;
    
    int main(void) {
      char ch = 'a';
      char *ptr = &ch;
      cout << ptr << endl;
      return 0;
    

    }

    输出

    =================================================================
    ==9156==ERROR: AddressSanitizer: stack-buffer-overflow on address 0xfffd3c71 at pc 0xf4de6974 bp 0xfffd3c30 sp 0xfffd3808
    READ of size 9 at 0xfffd3c71 thread T0
        #0 0xf4de6970 in strlen out/lib/compiler-rt-arm/out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:372:5
        #1 0x4cab5c in std::__ndk1::char_traits<char>::length(char const*) (/data/data/com.termux/files/home/dircpp/out+0x2b5c)
        #2 0x4ca144 in std::__ndk1::basic_ostream<char, std::__ndk1::char_traits<char>>& std::__ndk1::operator<<<std::__ndk1::char_traits<char>>(std::__ndk1::basic_ostream<char, std::__ndk1::char_traits<char>>&, char const*) (/data/data/com.termux/files/home/dircpp/out+0x2144)
        #3 0x4ca06c in main (/data/data/com.termux/files/home/dircpp/out+0x206c)
        #4 0xf4d0e61a in __libc_init (/apex/com.android.runtime/lib/bionic/libc.so+0x5a61a)
    
    Address 0xfffd3c71 is located in stack of thread T0 at offset 17 in frame
        #0 0x4c9f30 in main (/data/data/com.termux/files/home/dircpp/out+0x1f30)
    
      This frame has 1 object(s):
        [16, 17) 'ch' <== Memory access at offset 17 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 out/lib/compiler-rt-arm/out/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:372:5 in strlen
    Shadow bytes around the buggy address:
      0xf4af2730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af2740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af2750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af2760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af2770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    =>0xf4af2780: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1[01]f3
      0xf4af2790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af27a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af27b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af27c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0xf4af27d0: 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
    ==9156==ABORTING
    Aborted
    

    但每当我评论最后一行打印时,代码都能正常工作

    #include <iostream>
    using namespace std;
    
    int main(void) {
      char ch = 'a';
      char *ptr = &ch;
      //cout << ptr << endl;
      return 0;
    }
    

    如果我使用int而不是char数据类型,它会很好地工作。只有当我使用char类型时才会出现这个问题。

    1 回复  |  直到 2 年前
        1
  •  6
  •   Tim Roberts    2 年前

    当您打印 char * ,C++非常合理地假设您正在打印一个以零结尾的字符串。在您的情况下,您没有以零结尾的字符串。它在试图找到零终止符时跑进了未初始化的内存。如果要打印地址,请将其强制转换为 void * :

    cout << static_cast<void*>(ptr) << endl;
    
    推荐文章