在c ++中释放数组时堆损坏错误

时间:2015-01-06 19:05:24

标签: c++ arrays

我在c ++中运行代码时遇到问题。我有一个函数,我使用这个代码在其中动态定义了一个二维数组:

double** childs=new double *[2];
 for(int i=0;i<2;i++)
     childs[i]=new double[node];

代码工作正常,直到我决定在函数结束时释放该数组,我使用下面的代码:

for(int i=0;i<2;i++)
    delete []childs[i];

delete [] childs;

添加这部分代码后,运行时遇到问题,出现调试错误,如下图所示:

enter image description here

我搜索了很多,但我没有弄清楚问题是什么。我知道这个错误是为了解除分配部分,因为当我删除部分代码时效果很好。

有人可以帮帮我吗? 非常感谢

4 个答案:

答案 0 :(得分:2)

“我知道这个错误是为了解除分配部分,因为当我删除部分代码时效果很好。” - &GT;这不一定是真的。如果你弄乱了记忆,事情会在意想不到的地方破裂。例如,可能在代码的某个时刻,您正在编写数组外部,但是,当它尝试删除[]时会中断。

答案 1 :(得分:2)

你真正想做的是赶快去微软网站并获取windows的调试工具。我等了......

将gflags与pageheap选项一起使用。见http://msdn.microsoft.com/en-us/library/windows/hardware/ff549561(v=vs.85).aspx

Pageheap将使用在每次分配之前和之后放置受保护页面的分配器以及释放的块来更改进程的分配器。这样做的结果是,您可以通过pagefault立即检测到何时在分配的数据范围之外访问。

显然,您希望在调试器下运行您的应用程序以捕获该错误并找出您做错了什么。另外,请注意最好使用发布版本执行此操作,因为调试版本将在没有页面保护的内存分配周围具有保护字节,因此在测试时可能会出现误报。

祝你好运!

答案 2 :(得分:1)

没有足够的代码来确定内存被覆盖的位置,但是只需插入将打印所有指针值的打印语句,就可以在程序中找到这个位置。

例如

std::cout << childs << std::endl;
std::cout << childs[0] << std::endl;
std::cout << childs[1] << std::endl;

或者您可以尝试以下

std::cout << ( void * )( ( char * )childs - sizeof( int ) ) << std::endl;
std::cout << ( void * )( ( char * )childs[0] - sizeof( int ) ) << std::endl;
std::cout << ( void * )) ( char * )childs[1] - sizeof( int ) ) << std::endl;

或者你可以使用循环在循环中输出childs [0]和childs [1]。:)

答案 3 :(得分:1)

问题是你有代码写入&#34;保护字节&#34;已分配的空间,以及您检测到的Visual C ++应用程序的调试版本。

什么是&#34;保护字节&#34;?它们是在分配的空间之前和之后用信息写入的字节,并由运行时初始化为某个值。当需要释放内存时,运行时会检查这些保护字节以查看该值是否已更改。如果它们已经改变了,那么你在某个地方犯了一个错误,你无意中将数据写入这些字节占用的区域。

Visual C ++运行库无法在运行时检测到写入保护字节的时间。它只能在解除分配时检测到这一点。这就是为什么你认为你的程序正常工作&#34;,实际上它没有正常工作。

因此,通过检查数组索引的负值或超出数组范围的正值来查找覆盖。