我的代码中有一些链接列表。每个链表是 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 在 ZTE Parser [24.04.2012].exe 中触发了断点。
这可能是由于堆损坏,这表明 ZTE Parser [24.04.2012].exe 或其已加载的任何 DLL 中存在错误。
这也可能是由于用户在 ZTE Parser [24.04.2012].exe 具有焦点时按 F12。
当然我没有按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;
}
我认为如果内存分配或链接列表管理中存在任何漏洞,那么在打印列表时应该出现错误,或者至少某些数据必须作为垃圾出现,但它工作得很好。当我尝试释放内存时出现错误。任何帮助和想法将不胜感激。提前致谢。