c++ - 是否可以将一段内存标记为 "out of bounds",以便堆管理器不从中分配内存?

标签 c++ unit-testing dynamic-memory-allocation heap-memory

今天早些时候我问了this question .

在花了一些时间调查这个问题后,我发现了这是怎么回事。我将其作为一个新问题发布,因为我认为它很有趣,可以作为一个单独的问题进行跟踪。我将用答案更新该问题(以及指向该问题的链接)。

从调试器启动单元测试

// 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)总是返回内存中的相同地址。
  • 调试器启动单元测试时,随后调用new 分配对象(删除在分配新对象之前调用先前的 Object)始终返回内存中的唯一地址。

问题是因为 Object 的分配在通过命令行启动时总是在内存中获得相同的地址,我正在访问的 map 存储了指针仍然可以使用,测试不会崩溃。但我希望我的单元测试在缺陷修复未到位时崩溃,以确保它不会无声地失败并且缺陷不会再次出现。

我的问题分为两部分:

  1. 为什么堆管理器会在从命令行启动单元测试时重新使用相同的内存部分,而当我从调试器启动单元测试时却不会?

  2. 是否有我可以在我的测试工具上使用的编译器设置,或者我可以调用的方法来防止堆管理器重新使用我已删除的内存部分,以允许我正确地编写我的单元测试? 1


1显然,一种方法是不删除原始对象,但分配它的代码部分在我的生产代码中,我这样做会导致内存泄漏。

最佳答案

您的单元测试存在缺陷,因为它依赖于未定义的行为。您应该重写您的单元测试,使其不依赖于未定义的行为,在这种情况下,无论内存管理器如何决定分配内存,它都会始终通过。

你正在做的是这样的:

Object* pObject = new Object(...);
...
delete pObject;
pObject = new Object(...);
// Use dangling pointer to first object, and if it crashes, the unit test fails
// This is WRONG since a crash isn't guaranteed

您应该改为重构单元测试,使其像这样工作:

Object* pObject = new Object(...);
...
// Check to see if there are dangling references to pObject right before we
// delete it.  If there are, assert() and fail the unit test.
assert(NoDanglingReferences(pObject));
delete pObject;
// Continue on with more tests

关于c++ - 是否可以将一段内存标记为 "out of bounds",以便堆管理器不从中分配内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4274058/

相关文章:

c++ - QTextEdit 中的水平线

c++ - 在内存分配方面哪个更好 - 子对象或指向单独对象的指针?

c++ - 没有默认构造函数时,使用垃圾数据初始化对象

c - 我需要为我的作业创建三个单独的数组吗?

c++ - 在 C++ 中,数组分配的 new 和 new[] 有什么区别

c++ - 我是 C++ 的新手,正在努力弄清楚为什么我的代码可以完美运行,但在运行后仍然返回一个荒谬的数字

c++ - 防止被零除的适当行为

c - 嵌套预处理器指令或其他技巧以有条件地重新定义 static 关键字

.net - 如何在 VSCode 中调试 MSTest?

sql - 对内存中可与持续交付管道集成的数据库过程进行VS单元测试