c - Visual C++ 2010 堆损坏

标签 c linked-list free heap-corruption memory-corruption

我的代码中有一些链表。每个链表都是 C 代码中一个大结构的一部分,它是一个函数的局部变量。该代码使用另一个函数来填充列表,执行一些其他操作,然后调用第三个函数来打印和删除它。第一个节点不需要删除。

问题: 该函数正确打印所有数据,因此没有悬空指针等。但是当我尝试释放内存时,出现堆损坏错误。引发此错误的一个代码示例是:

flag = 0;

while( stpBS_current != NULL && stpFlags_current != NULL ){
// Linked list printing code is removed for clarity
    if( flag == 1 ){
        stpPrev = stpBS_current;
        stpFlags_prev = stpFlags_current;

        stpBS_current = (struct BasicService *)stpBS_current->pNext;
        stpFlags_current = (struct BasicService_Flags *)stpFlags_current->pNext;

        free( stpPrev );
        free( stpFlags_prev );
    }
    else
    {
        stpBS_current = (struct BasicService *)stpBS_current->pNext;
        stpFlags_current = (struct BasicService_Flags *)stpFlags_current->pNext;

        flag = 1;
    }
}

stpPrevstpFlags_prev 是局部变量,stpBS_currentstpFlags_current 在打印/删除中作为参数传递功能。执行转换是因为原始链表具有void *。由于同一函数正确打印了所有存储的数据,并且此内存尚未在其他地方释放,因此我确定指针是正确的。

我在这里完全不知所措。 Google 上的所有内容都与缓冲区溢出有关,但我确信情况并非如此。我正在使用 MS Visual C++ 2010,它显示的错误是:

Windows has triggered a breakpoint in ZTE Parser [24.04.2012].exe.

This may be due to a corruption of the heap, which indicates a bug in ZTE Parser [24.04.2012].exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while ZTE Parser [24.04.2012].exe has focus.

当然,我没有按 F12,所以这是不可能的。 如果我忽略第一个错误并继续执行代码,那么在返回之前我会从对 free() 的同一次调用中得到几个断言失败,并最终以:

结束

MS VS 2010 Heap Corruption Snapshot

void 指针是罪魁祸首吗?但毕竟 malloc() 和 free() 使用 void 指针所以 IMO 这应该不是问题。 我相信堆是一个全局内存,因此在不同的函数中分配和取消分配应该不是问题。

分配内存的代码很简单(2 个链表)。为了清楚起见,我删除了头节点初始化代码:

stpBSC_current->pNext   =   malloc( sizeof(struct BasicServiceCode) );
stpFlags_current->pNext =   calloc( 1, sizeof(struct BasicServiceCode_Flags) );

if( stpBSC_current->pNext == NULL || stpFlags_current->pNext == NULL )
    exit( 1 );
else
{
    stpBSC_current      =   (struct BasicServiceCode *)stpBSC_current->pNext;
    stpFlags_current    =   (struct BasicServiceCode_Flags *)stpFlags_current->pNext;
}

我认为如果内存分配或链接列表管理中存在任何循环漏洞,那么错误应该在打印列表时出现,或者至少一些数据必须作为垃圾输出,但它工作得很好。当我尝试释放内存时出现错误。任何帮助和想法将不胜感激。提前致谢。

最佳答案

事实证明标志条件不正确(问题中未显示某些打印代码)。

原因: free() 试图释放未使用 malloc() 分配的头节点。它是一个静态分配的变量。因此,从技术上讲,这并不是初始错误所暗示的堆损坏,但正如断言失败错误所指定的那样,free() 试图释放位于 开始之前的一些内存堆缓冲区,当然在堆栈上。这是导致错误的原因。

@everyone 感谢您的帮助和建议。

关于c - Visual C++ 2010 堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13071621/

相关文章:

c - 多维 C 数组

java - 对象值为空

c - 函数,链表。将一个链表复制到另一个链表

c - 打印链接列表,不打印任何内容

无法释放结构体的数据

c - 在 C 中释放一棵树

c - sscanf 循环仅多次读取第一个输入

c - 为什么这个 print 语句会出错?

更改 gdb 中的默认主文件

c - 这是为数组分配内存的好方法吗? (C)