[学习]动态内存分配导致的堆溢出问题:Critical error detected c0000374

今天在写霍夫曼树的例程的时候遇到了一个较为棘手的错误,在这里记录一下

如图所示,在运行

HT.tree = (HuffmanTree<int>::HTNode*)malloc((m + 1) * sizeof(HuffmanTree<int>::HTNode));

时vs给出了一个奇怪的错误,这个错误没有报错提示,在继续运行之后继续显示

这里的“堆”代表的是

堆:操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。 另外由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
www.cnblogs.com/George1994/p/6399895.html

换句话说,操作系统给客户程序用于动态申请和释放的空间称为堆。

此处的“堆损坏”就是此链表内部的数据检查不通过,换句话说,里面的未分配的空间上的值被修改了。由于堆作为链表可以随机访问,因此对于其访问域的限制便没有那么完善,因而可能在未申请的情况下直接访问某些不应该访问的堆的值,此时操作系统分配空闲空间的时候检查不通过,从而导致堆损坏。

例如下述程序:

int* test_heap_alloc()
{
	int* pTable = new int(256); // 申请一个int结构体变量,初始值为256;
	for (int i = 0; i < 256; i++)
		pTable[i] = i;
	return pTable;
}
int main(int argc, char** argv) {

	test_heap_alloc();
	return 0;
}

https://blog.csdn.net/chunyexiyu/article/details/120233683

(由于vs的intelliSence比较智能,此处通过RangeChecks即发现了对堆的越界访问:

0x77E0A37B (ntdll.dll) (CppHomeworkFramework.exe 中)处有未经处理的异常: RangeChecks 检测代码检测到超出范围的数组访问。

而观察这段程序,其实这段程序已经成功造成了堆溢出,其关键在于对数组的非法下标访问。这个下标(自1开始)都没有申请。


因此解决方案很简单:检查已有代码,查看是否存在上述的越界操作。

posted @ 2021-12-05 21:15  二氢茉莉酮酸甲酯  阅读(1437)  评论(0编辑  收藏  举报