今天早些时候我问了这个问题。
在花了一些时间调查这个问题之后,我发现了发生了什么。我将此作为一个新问题发布,因为我认为将其作为一个单独的问题进行跟踪很有趣。我将用答案更新该问题(以及指向此问题的链接)。
从调试器启动单元测试
// Construct object
Object* pObject = new Object(...);
// Pointer value of pObject == 0x05176960
// Lots of other code
// ...
// Destroy object
delete pObject;
// Construct object again
pObject = new Object(...);
// Pointer value of pObject == 0x05560194 /* Different memory location */
从命令行启动单元测试
// Construct object
Object* pObject = new Object(...);
// Pointer value of pObject == 0x05176960
// Lots of other code
// ...
// Destroy object
delete pObject;
// Construct object again
pObject = new Object(...);
// Pointer value of pObject == 0x05176960 /* Same memory location */
总之:
- 从命令行启动单元测试时,后续调用
new
分配一个Object
(在分配新delete
的Object
之前)总是在内存中返回相同的地址。 - 从调试器启动单元测试时,后续调用
new
分配一个Object
(在分配新delete
的Object
之前分配前一个)总是返回内存中的唯一地址。
问题是,因为Object
在通过命令行启动时分配总是在内存中获得相同的地址,所以我正在访问的已存储旧指针的映射仍然可以使用并且测试不会崩溃。但是我希望我的单元测试在缺陷修复不到位时崩溃,以确保它不会静默失败并且缺陷不会再次出现。
我的问题有两个部分:
为什么堆管理器会在从命令行启动单元测试时重用内存的同一部分,但在我从调试器启动单元测试时却不会?
是否有我可以在我的测试工具上使用的编译器设置,或者我可以调用的方法来防止堆管理器重新使用我已删除的一段内存,以允许我正确编写我的单元测试? 1
1显然,这样做的一种方法是不删除原始对象,但分配这个的部分代码在我的生产代码中,我这样做会导致内存泄漏。