【发布时间】:2018-06-22 18:29:21
【问题描述】:
我正在学习 valgrind 框架,我决定在我自己的小测试用例上运行它。这是以下程序,它强制从堆中删除额外的对象(我在 AMD64/LINUX 上运行它):
#include <iostream>
using namespace std;
struct Foo
{
Foo(){ cout << "Creation Foo" << endl;}
~Foo(){ cout << "Deletion Foo" << endl;}
};
int main()
{
Foo* ar = new Foo[3];
*(reinterpret_cast<int*>(ar)-2) = 4;
delete[] ar;
return 0;
}
但是 valgrind 的执行结果真的让我很困惑:
$ valgrind --leak-check=full ./a.out -v
==17649== Memcheck,内存错误检测器
==17649== 版权所有 (C) 2002-2017 和 GNU GPL,由 Julian Seward 等人撰写。
==17649== 使用 Valgrind-3.13.0 和 LibVEX;使用 -h 重新运行以获取版权信息
==17649== 命令:./a.out -v
==17649==
创世符
创世符
创世符
删除 Foo
删除 Foo
删除 Foo
删除 Foo
==17649==
==17649== 堆摘要:
==17649== 退出时使用:72,704 个字节,1 个块
==17649== 总堆使用量:3 次分配,2 次释放,73,739 字节分配
==17649==
==17649== 泄漏摘要:
==17649== 肯定丢失:0 个块中的 0 个字节
==17649== 间接丢失:0 个块中的 0 个字节
==17649== 可能丢失:0 个块中的 0 个字节
==17649== 仍可访问:1 个块中的 72,704 个字节
==17649== 抑制:0 个块中的 0 个字节
==17649== 可达块(找到指针的那些块)未显示。
==17649== 要查看它们,请重新运行:--leak-check=full --show-leak-kinds=all
==17649==
==17649== 对于检测到和抑制的错误计数,重新运行:-v
==17649== 错误摘要:0 个上下文中的 0 个错误(已抑制:0 个来自 0)
valgrind(版本 3.13.0)似乎没有检测到任何内存损坏?
UPD:我用命令g++ -g main.cpp编译了main.cpp
【问题讨论】:
-
*(reinterpret_cast<int*>(ar)-2) = 4;是一种潜在的严格别名违规,会导致未定义的行为,并且是在发布模式下优化的潜在目标,会丢弃整行。你是如何编译这段代码的? -
@VTT,我更新了问题。我知道这是肮脏的 hack - 我只是想隐式更改数组中分配对象的数量
标签: c++ debugging memory memory-management valgrind