【发布时间】:2011-11-30 16:03:44
【问题描述】:
一个进程因 SIGSEV 而崩溃,并且回溯表明内存损坏。 Valgrind 报告表明存在一些“不匹配的空闲空间”,即使用 new[] 分配的内存正在使用 free() 释放。
我找到了以下information from cert.org
另一个潜在的问题是,当将指针传递给使用 operator new 分配给 operator delete() 的数组时,可能会在 operator delete() 调用 free() 时(这在许多实现中很常见,尽管不是C++ 标准要求),传递给 free() 的指针不是调用 malloc() 返回的指针。这是因为 malloc() 在 operator new 调用时返回的前四个字节通常用于存储数组的大小(同样,标准未指定,但常见),因此 operator new 返回的指针实际上指向到距离 malloc() 返回的指针四个字节的地址。因此,free() 将读取错误的大小以进行释放,这可能会导致堆内存损坏问题。
问题是,我如何证明 free() 释放了错误的大小?任何人都可以建议如何验证这是否发生在我的环境中,也许使用 gdb 或任何其他工具?
此外,该数组是基本类型 char,因此不存在不调用单独的析构函数的问题。
【问题讨论】:
-
没什么意义,你已经知道程序在 UB 上崩溃了。无需证明。
-
不要试图证明 free() 正在释放错误的大小。如果您使用
new[]进行分配并使用delete[]以外的其他内容进行分配,则会导致未定义的行为。事后不要试图分析你的程序。在操作中捕获错误的释放(您可能可以使用 Valgrind)并修复它。 -
valgrind绝对是非常准确方便地指出此类问题的首选工具之一。 -
我不确定如何验证它的实际作用,但你能确认你是在调用
delete[]而不是delete吗? -
你是为了学术兴趣还是在实际的实际程序中尝试这个?如果是后者,这没有什么意义,因为一旦您在分配有
new的任何东西上使用free,它就是一个保证的未定义行为,标准不保证在这种未定义行为场景中实现应该做什么。
标签: c++ memory-management