我有一个BYTE数组如下:
BYTE* m_pImage;
m_pImage = new BYTE[m_someLength];
在程序的各个阶段,数据被复制到这个数组中,如下所示:
BYTE* pDestinationBuffer = m_pImage + m_imageOffset;
memcpy( pDestinationBuffer, (BYTE*)data, dataLength );
但是当我像这样删除我的缓冲区时:
delete[] m_pImage;
我得到了 HEAP CORRUPTION DETECTED - CRT检测到应用程序在堆缓冲区结束后写入内存
现在我已经尝试了一个简单的程序来尝试复制错误,以帮助我调查最新情况。我从下面看到,如果我创建一个大小为5的数组但是在它的末尾写入并尝试删除它我会得到完全相同的错误。
int* myArray = new int[5];
myArray[0] = 0;
myArray[1] = 1;
myArray[2] = 2;
myArray[3] = 3;
myArray[4] = 4;
myArray[5] = 5; // writing beyond array bounds
delete[] myArray;
现在我的问题是如何调试或找出覆盖原始缓冲区的内容。我知道有些东西会覆盖缓冲区的末尾,所以Visual Studio有一种方法可以帮助我轻松地调试它。
上面复制到数据缓冲区的代码在删除之前会多次调用,以便跟踪m_pImage内容和复制到它的数据。 (它大约有2M的数据)
答案 0 :(得分:2)
现在我的问题是如何调试或找出覆盖原始缓冲区的内容。
我建议尽可能使用assert()
语句。在这种情况下,它应该是:
BYTE* pDestinationBuffer = m_pImage + m_imageOffset;
assert( dataLength + m_imageOffset <= m_someLength );
memcpy( pDestinationBuffer, (BYTE*)data, dataLength );
然后编译成调试模式并运行。这种方法的好处 - 在释放模式下你不会有任何开销,其中不会评估断言。
答案 1 :(得分:0)
在Windows上,您可以使用Application Verifier查找此类覆盖
答案 2 :(得分:0)
堆腐败是一个难以找到的错误。大多数情况下,当报告错误时,内存已被先前执行的某些上游代码破坏。如果你决定使用Application Verifier(你应该),我也建议你试试GFLags and PageHeap。它们是一些额外的工具,允许您设置注册表标志以调试这些类型的问题。