我的代码中有一些链表。每个链表都是 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;
}
}
stpPrev
和 stpFlags_prev
是局部变量,stpBS_current
和 stpFlags_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()
的同一次调用中得到几个断言失败,并最终以:
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/