c - dbgheap.c 尝试重新分配时出错 *向数组添加空间*

标签 c

为学校创建一个优先队列。使用指向对象的指针数组来保存信息。如果条目数太大,我希望能够动态地向数组添加更多空间。下面是我如何初始化数组的原始大小。 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() 内存不足:

  1. 插入函数调用 pq_addMem() 以获得更多空间
  2. pq_addMem() 双倍 pq->pq_max
  3. realloc() 返回NULLpq->Array 保持相同大小。
  4. pq_addMem() 返回。
  5. insert 函数发现 pq->pq_max 现在变大了,继续在数组末尾插入节点,覆盖内部堆数据。
  6. ...
  7. 稍后调用内存管理函数试图解释损坏的堆,一切都乱套了。

仔细检查您所有的指针和数组访问,确保所有内容确实是您认为的大小,并留意偷偷摸摸的东西,例如无意中 malloc()'ing 0 字节然后尝试实际使用它愉快地返回的指针。

关于c - dbgheap.c 尝试重新分配时出错 *向数组添加空间*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21319021/

相关文章:

c - 跟踪 Pthread 完成的顺序

c - 运行机器代码时出现模糊的运行时错误

c - 某些C表达式在其语法中允许,而在实践中编译时不允许,这是否正常?

c - 如何使用 libAV 库(ffmpeg)将 H264 编码数据放入 .mp4 等容器中?

c - 如何将 C 代码编译成固件补丁并获取所有函数的位置?

c - 从命令行将输出重定向到 C 中的文本文件

c - 如何在 C 中使用 UDP 分配 PacketID 来跟踪不可靠网络上的数据包?

c - 描述符中的 SQLSET 数据类型

c - 两个节点内数据相同但不相等

c - C99 中的 Variadic 函数可以释放多个数组?