c++ - 对象内的 Valgrind 数组溢出

标签 c++ valgrind overrun

我有一个简单的程序如下。

struct Test
{
    int a[5];
    int b;
};

int main()
{
    Test* t = new Test;
    t->b = 1;
    t->a[5] = 5;          //This is an illegal write
    cout << t->b << endl; //Output is 5
    return 0;
}

用Valgrind Memcheck运行没有报非法内存写入。

我注意到 Valgrind 声称 Memcheck 工具无法检测全局或堆栈数组溢出,但这个数组在堆中,对吧?只是数组在一个对象中。

是Valgrind真的检测不到这种错误还是我做错了什么?如果是前者,那么是否有任何其他工具可以检测此类错误?

============================================= ===========================

更新:

我使用的编译命令是g++ -O0 -g main.ccvalgrind 命令只是 valgrind ./a.out,默认情况下应调用 memcheck 工具。

编译器版本为gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)valgrind版本为valgrind-3.5 .0

运行此程序时的 Valgrind 输出:

==7759== Memcheck, a memory error detector
==7759== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==7759== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==7759== Command: ./a.out
==7759== 
5
==7759== 
==7759== HEAP SUMMARY:
==7759==     in use at exit: 24 bytes in 1 blocks
==7759==   total heap usage: 1 allocs, 0 frees, 24 bytes allocated
==7759== 
==7759== LEAK SUMMARY:
==7759==    definitely lost: 24 bytes in 1 blocks
==7759==    indirectly lost: 0 bytes in 0 blocks
==7759==      possibly lost: 0 bytes in 0 blocks
==7759==    still reachable: 0 bytes in 0 blocks
==7759==         suppressed: 0 bytes in 0 blocks
==7759== Rerun with --leak-check=full to see details of leaked memory
==7759== 
==7759== For counts of detected and suppressed errors, rerun with: -v
==7759== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

最佳答案

我认为下面的句子,你已经找到了:

Memcheck cannot detect every memory error your program has. For example, it can't detect out-of-range reads or writes to arrays that are allocated statically or on the stack. But it should detect many errors that could crash your program (eg. cause a segmentation fault).

如果你的类定义应该这样解释: 虽然类对象是动态分配的,但数组本身是静态分配的

我已经验证了几个案例:

如果数组是动态分配的,Valgrind 将报告无效写入:

struct Test
{
    int *a;
    int b;
};

int main()
{
    Test* t = new Test;
    t->a = new int[5];
    t->b = 1;
    t->a[5] = 5;          //This is an illegal write
    cout << t->b << endl; //Output is 5
    delete [] t->a;
    delete t;
    return 0;
}

如果您将成员的顺序更改为:也会报错:

struct Test
{
  int b;  
  int a[5];
};

这是因为当尝试写入 a[5] 时,我们已经落后于动态分配的对象。

使用原始类定义,如果您尝试写入 a[6] - 因为那样我们就在 b 后面,所以在动态分配的对象后面。


更新:gcc sanitizer(我也怀疑 clang)通过编译在运行时检测到这种越界访问:

g++ -fno-omit-frame-pointer -fsanitize=bounds m.cpp

输出:

m.cpp:15:7: runtime error: index 5 out of bounds for type 'int [5]'

关于c++ - 对象内的 Valgrind 数组溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44815636/

相关文章:

c++ - 根据 GPU 计算能力定义 MACRO

c++ - 使用 QThread 时类型转换和 QThreadStorage 警告?

无法使用 FFT 和 FFTW 检索原始图像

c - Valgrind 大喊未初始化的字节

c - valgrind 发现无效写入和读取的数量令人难以置信

java - 在 Java 中将 long 转换为 byte

c++ - 如何配置 CMake 以使用 -fPIC 构建库?

c++ - 包含 cmath header 时 Cmake 编译错误