偶尔您会遇到只能在发布版本中和/或仅在某些计算机上可重现的错误。一个常见的(但绝不是唯一的)原因是未初始化的变量,它们受随机行为的影响。例如,在大多数机器上,未初始化的BOOL大部分时间都可以为TRUE,但随机初始化为FALSE。
我希望我能通过修改CRT内存初始化的行为来系统地清除这些错误。我很清楚MS调试CRT magic numbers - 至少我想要一个触发器将0xCDCDCDCD(初始化新分配的内存的模式)转为零。我怀疑一个人能够轻易地抽出令人讨厌的东西 即使在调试版本中,初始化也会以这种方式进行害虫攻击。
我是否错过了启用此功能的可用CRT挂钩(API,注册表项等)?任何人都有其他想法到达那里?
[编辑:] 似乎有必要进行澄清。
[编辑:] @Michael,不确定覆盖新内容是什么意思。简单的代码,如 -
void* new(...)
{
void* res = ::new(...); // constructors now called!
if(SomeExternalConditionApplies())
OverWriteBufferWithMyPetValues(res);
}
无效。粘贴和修改整个::新代码可能会有效,但看起来有点可怕(上帝只知道我需要#include和链接以使其运行)。
答案 0 :(得分:3)
我没有关注 - 将未初始化的内存设置为类似0xcdcdcdcd
而不是0 更好来清除错误,因为代码更有可能获得'范围'算术或特别处理0.由于值非常无效,错误更有可能“快速失败”,因此可以修复而不是隐藏。
MSVC的调试版本使用的值专门用于帮助导致可以轻松检测到的错误:
此外,它们在调试器中的数据显示中很容易识别。 Zero几乎没有那么突出。
所有这一切,MSVC提供了许多调试钩子/ API,您可以使用它们来执行您想要的任务:
针对您更新的问题的一些其他信息:
您可以使用像Dmalloc(http://dmalloc.com/)这样的第三方调试分配库,但老实说,我不知道这些库可以轻松地集成到MSVC项目中,尤其是“真实世界”项目。
另外,请注意,这些显然只会处理动态分配(并且可能无法与MSVC的默认new
实现很好地集成)。
你可以使用operator new()
的全局覆盖来处理在C ++中使用new
发生的分配 - 覆盖任何有效的构造函数初始化没有问题 - { {1}}分配在构造函数执行任何初始化之前发生(如果你想一下它应该清楚为什么会这样)。
此外,您可能需要考虑迁移到Visual Studio 2010 - 当您使用未初始化的局部变量时,它将进入调试器 - 除了在调试器下运行Debug构建之外,什么都不做。当然,MSCV已经对这些情况中的许多情况进行了一段时间的警告,但VS2010将在调试器中捕获以下内容,这不会产生任何警告(至少使用我当前的编译器设置):
new
即使是VC ++ 2010的Express版本也支持这一点。
答案 1 :(得分:1)
只是一个建议:您可以在编译器中使用静态代码分析工具吗? / analyze会给你一个C6001警告你正在使用未初始化的内存。它有点系统化,这就是你的要求。
答案 2 :(得分:1)
单步进入CRT会显示_heap_alloc_dbg和realloc_help中使用的幻数,并且值本身编码为
static unsigned char _bCleanLandFill = 0xCD; /* fill new objects with this */
知道搜索often helps的内容。链接的线程确实有一个很好的建议:在_bCleanLandFill上设置一个监视并从调试器修改它。
它确实有效,但我会暂时保持这个问题 - 我仍然希望有人有更好的想法...我希望能够通过受控初始化来运行自动化测试,而不必手动完成(和只有调试器可用)。