当前位置:  开发笔记 > 编程语言 > 正文

VC++中未初始化的内存块

如何解决《VC++中未初始化的内存块》经验,为你挑选了6个好方法。

众所周知,Visual C++运行时标记未初始化或刚刚释放的具有特殊非零标记的内存块.有没有办法完全禁用此行为,而无需手动将所有未初始化的内存设置为零?这是因为我的有效非空检查造成了破坏0xFEEEFEEE != 0.

嗯,也许我应该更好地解释一下.我创建并初始化一个变量(通过new),一切都很好.当我释放它(通过删除)时,它将指针设置为0xFEEEFEEE而不是NULL.当我插入一个适当的检查NULL,因为所有管理自己的内存的好程序应该,我提出问题,因为0xFEEEFEEE通过NULL检查没有问题.有没有什么好的方法,除了NULL在删除它们时手动设置所有指针,以检测何时已释放内存?我宁愿不使用Boost只是因为我不想要开销,虽然它可能很小,因为这是我唯一使用Boost的东西.



1> Eclipse..:

创建指针时,explicity将其初始化为NULL.同样在一个delete.取决于未初始化数据的值(除少数特定情况外)是在寻找麻烦.

通过使用智能指针类(例如boost::shared_ptr)可以自动处理是否初始化指针,可以避免很多麻烦.


完全同意.应始终将新内存初始化为零.作为一方,我注意到的一件事是在删除之前不必要地检查ptr!= NULL.删除NULL指针总是安全的.不是未初始化的ptr的情况.

2> Rob Walker..:

VC++的行为不应该导致你可以做的任何有效检查造成严重破坏.如果你看到0xfeeefeee然后你没有写入内存(或已经释放它),所以你不应该从内存中读取.



3> Andy Ross..:

如果您正在阅读未初始化的内存,那么您的检查肯定不是"有效".内存被释放.它可能已经被用于其他东西.您不能对C/C++中未初始化的内存的内容做任何假设.

Java(和C#,我相信)将保证在使用之前将分配的内存归零,当然垃圾收集会阻止您看到释放的内存.但这不是C堆的属性,它直接暴露内存.



4> Adam Rosenfi..:

如果您在Release模式而不是Debug模式下构建,则运行时根本不会填充未初始化的内存,但它仍然不会为零.但是,你应该依赖于这种行为-你应该明确地自己初始化内存memset的(),ZeroMemory(),或SecureZeroMemory(),或设置一个标志的地方,表明该内存尚未初始化.读取未初始化的内存将导致未定义的行为.



5> Ted..:

delete重置所有指向对象的指针不是责任NULL.此外,您不应该更改Windows DEBUG运行时的默认内存填充,您应该使用像boost::shared_ptr<>指针一样的东西.

也就是说,如果你真的想用脚射击自己,你可以.

您可以使用这样的分配器挂钩更改 Windows DEBUG运行时默认填充.这只适用于HEAP分配的对象!

int main(int argc,char** arv)
{
  // Call first to register hook    
  _CrtSetAllocHook(&zero_fill);
  // Do other stuff
  malloc(100);
}


int zero_fill(int nAllocType, 
              void* pvData, 
              size_t nSize,
              int nBlockUse, 
              long lRequest, 
              const unsigned char *szFileName, 
              int nLine )
{
  /// Very Importaint !! 
  /// infinite recursion if this is removed !!
  /// _CRT_BLOCK must not do any thing but return TRUE
  /// even calling printf in the _CRT_BLOCK will cause
  /// infinite recursion
  if ( nBlockUse == _CRT_BLOCK )
    return( TRUE );
  switch(nAllocType)
  {
  case _HOOK_ALLOC:
  case _HOOK_REALLOC:
    // zero initialize the allocated space.
    memset(pvData,0,nSize);
    break;
  case _HOOK_FREE:
    break;
  }
  return TRUE;
}


谢谢,我添加了适当的免责声明.

6> Michael Burr..:

你说:

我创建并初始化一个变量(通过new),一切都很好.当我释放它(通过删除)时,它将指针设置为0xFEEEFEEE而不是NULL.当我插入一个正确的NULL检查,因为所有管理自己内存的好程序应该,我提出问题,因为0xFEEEFEEE传递NULL检查没有问题.

即使是MSVC的调试堆程序将不会改变的价值指针你删去-你删除不会改变(甚至为NULL)指针的值.听起来你正在访问一个属于你刚刚删除的对象的指针,这是一个简单明了的bug.

我很确定你要做的事情只会掩盖无效的内存访问.您应该发布一段代码来向我们展示实际发生的情况.

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有