我的代码中有一些链接列表。每个链表都是C代码中大型结构的一部分,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
作为参数在print/delete函数中传递。因为原始链表具有void *
,所以执行转换。因为同一个函数正确地打印了所有存储的数据,而这个内存没有在其他地方释放,所以我确信指针是正确的。我在这里完全不知所措。Google上的一切都是关于缓冲区溢出的,但我相信情况并非如此。我使用MS Visual C++ 2010,它显示的错误是:
Windows在中兴通讯解析程序[24.04.2012].exe中触发了断点。
这可能是由于堆损坏,这表明
中兴通讯解析程序[24.04.2012].exe或它加载的任何dll。
这也可能是由于用户在中兴通讯解析器中按下F12键
[24.04.2012].exe有焦点。
当然我还没按F12,所以这是不可能的。
如果我忽略第一个错误并继续执行代码,那么在它返回之前,我会从
free()
的同一个调用中得到两个断言失败,并最终导致:空指针是罪魁祸首吗?但毕竟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()
试图释放堆栈上堆缓冲区开始之前的一些内存。这是导致错误的原因。
@谢谢大家的帮助和建议。
关于c - Visual C++ 2010堆损坏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13071621/