testingC ++代码和IsBadWritePtr

我目前正在为我的C ++代码的某些function编写一些基本的testing(这是我主要为了教育目的而编写的游戏引擎)。 我想testing的function之一是内存分配代码。 如果代码处于debugging模式,testing目前由一个运行每个启动的函数组成。 这迫使我在debugging时总是testing代码。

为了testing我的内存分配代码,我的本能是做这样的事情:

int* test = MemoryManager::AllocateMemory<int>(); assert(!IsBadWritePtr(test, sizeof(int)), "Memory allocation test failed: allocate"); MemoryManager::FreeMemory(test); assert(IsBadWritePtr(test, sizeof(int)), "Memory free test failed: free"); 

此代码工作正常,但所有资源,我可以find说不要使用IsBadWritePtr函数(这是一个WinAPI函数为陌生人)。 在这种情况下使用这个函数是OK的吗? 我发现的三个主要警告是:

这可能会导致警卫页面的问题

这不是一个问题,因为内存分配代码就在那里,我知道我没有分配一个保护页面。

早点失败会更好

这不是一个考虑因素,因为我从字面上使用它来尽早失败。

这不是线程安全的

testing代码在执行开始时就已经被执行了,就在任何其他线程存在之前。 它也作用于没有其他指针创build的内存,因此不能存在于其他线程中。

所以基本上我想知道在这种情况下使用这个函数是否是一个好主意,以及是否有什么我失踪的function。 我也知道指向错误位置的东西仍然会通过这个testing,但是它至less可以检测到大部分的内存分配错误,对(如果分配失败,我得到一个指向有效内存的指针的机会是多less?)

我打算把这个作为评论来写,但是太长了。

我会在房间里调出大象:为什么不用传统的方式来测试失败(通过返回null或抛出异常)?

不要忘记,IsBadWritePtr是如此皱眉(即使它的文档说,它已经过时,你不应该使用它),但你的用例似乎并不合适。 从MSDN文档:

此函数通常用于处理从第三方库返回的指针时,在第三方DLL中您不能确定内存管理行为。

但是你没有使用它来测试从DLL传递/返回的东西,你似乎正在使用它来测试分配成功,这不仅是不必要的(因为你已经知道从HeapAlloc,GlobalAlloc等的返回值),但这不是IsBadWritePtr的目的。

此外,测试分配成功不是你应该只在调试模式下或断言,因为它显然超出了你的控制,你不能通过调试来“修复”它。

建立在@ user1610015的答案,有一个原因为什么IsBadReadPtr不应该在您的方案中工作。

基本上IsBadReadPtr工作在整个页面的粒度。 这意味着上面的代码是正确的,每个分配你将会占用整个页面(分钟4KB)。

现代分配器使用各种技巧将大量分配打包到页面中(低碎片桶堆,分配的链接列表等)。 如果你不打包像这样的小分配,然后认为像STL地图和其他库使用大量的小分配将绝对杀死你的游戏(无论是在内存使用和高速缓存一致性将被杀死这么多未使用的填充)。

作为一个方面,你最后一个关于线程安全的评论是危险的。 你链接的许多应用程序和库可以使用全局对象构造函数产生线程(并在main调用之前运行)以及其他技巧将代码插入到进程中。 所以我肯定会检查这是你的代码现在的情况,但更重要的是,当你添加第三方库到你的代码检查它。