为学校创建一个优先队列。使用指向对象的指针数组来保存信息。如果条目数太大,我希望能够动态地向数组添加更多空间。下面是我如何初始化数组的原始大小。 pq_max 是 1024 开始。由于它是一个树结构,如果它需要更多空间,我只想将大小加倍。
因此,如果需要更多空间,我告诉我的插入函数调用 pq_addMem,但它失败了。进一步调试后,我传递了一个错误的指针或来自非本地堆的指针。
我习惯了 C++ 并假设我重新分配内存不正确,但无法弄清楚原因。如果答案对某些人来说不是很明显,我会发布其余代码。
pq->Array = (pq_entry_t*) malloc( sizeof(pq_entry_t) * (pq->pq_max) );
void pq_addMem(pq_t* pq)
{
pq_entry_t *newArray;
pq->pq_max *= 2;
newArray = (pq_entry_t*) realloc(pq->Array, sizeof(pq_entry_t) * pq->pq_max);
if (newArray == NULL)
{
return;
}
else
{
pq->Array = newArray;
}
}
失败的地方。
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
最佳答案
这里实际上只有两种可能性 - pq->Array
被修改为不同于 malloc()
的返回值或 realloc ()
,当您将它传递给 realloc()
时调用未定义的行为,或者堆以某种方式被破坏,在这种情况下几乎任何事情都可能发生 .
指针很容易调试 - 在每个 malloc()
、realloc()
和 free()
处设置断点以确保值是正确的在两者之间改变。如果是,追踪时间、地点和原因。
另一方面,堆损坏通常是调试的痛点,因为您通常只会在它发生后的某个时间看到症状,并且您得到的错误通常是无意义的,只会告诉您出了点问题.
现在,在发布的代码中有一个潜在的堆损坏等待发生,但它似乎不是导致这次崩溃的原因。考虑何时 realloc()
内存不足:
- 插入函数调用
pq_addMem()
以获得更多空间 pq_addMem()
双倍pq->pq_max
realloc()
返回NULL
,pq->Array
保持相同大小。pq_addMem()
返回。- insert 函数发现
pq->pq_max
现在变大了,继续在数组末尾插入节点,覆盖内部堆数据。 - ...
- 稍后调用内存管理函数试图解释损坏的堆,一切都乱套了。
仔细检查您所有的指针和数组访问,确保所有内容确实是您认为的大小,并留意偷偷摸摸的东西,例如无意中 malloc()
'ing 0 字节然后尝试实际使用它愉快地返回的指针。
关于c - dbgheap.c 尝试重新分配时出错 *向数组添加空间*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21319021/