在标准C语言中,malloc() 和 free()是一对操作,有malloc()之后要有free()释放内存。另外在C++中也有一对类似的操作new 和delete,这两对完成的功能类似,但是这两对稍稍有些不同,这些就不讨论它们的区别,只讨论free()的坑。
1.free()并不是真正意思上的释放内存:
free释放掉指定参数指针指向的内存,并返回void。其实,free函数只是将参数指针指向的内存归还给操作系统,并不会把参数指针置NULL,为了以后访问到被操作系统重新分配后的错误数据,所以在调用free之后,通常需要手动将指针置NULL。从另一个角度来看,内存这种底层资源都是由操作系统来管理的,而不是编译器,编译器只是向操作系统提出申请。所以free函数是没有能力去真正的free内存的。只是告诉操作系统它归还了内存,然后操作系统就可以修改内存分配表,以供下次分配。
2.free()的时候程序宕机,很多时候都是和内存溢出或者说内存分配问题有关(若遇到相关问题,可以多往这上面想):
一句话就是你想释放的内存和你释放的内存不一致,很多时候是大小不一致。下面以本人在链表的节点释放问题遇到的蠢事:
int DestoryList(_Cicle_List **head)
{
int ret = 0;
if (head == NULL)
{
printf("Parameters Error :DestoryList() \n");
ret = -1;
return ret;
}
Cicle_List *header = (Cicle_List *)*head;
Circle_ListNode *current = header->Head.Next; //current指向0号位置
Circle_ListNode *temp = current->Next; //temp指向1号位置
for (int i=0; i<header->ListLen-1; i++)
{
if (current != NULL)
{
free(current); // bug 出现在这里
}
current = temp;
temp = current->Next;
}
header->Cursor.Next = NULL;
header->ListLen = 0;
*head = NULL;
return ret;
}
在销毁链表的时候,想把一个一个的数据节点所释放掉 ,问题的原因如下
这里free()总是报错,为什么,
因为在分配的时候,代码:Cicle_List *CircleListHead = (Cicle_List *)malloc(sizeof(Cicle_List)); 上面只开辟了sizeof(Cicle_List)个内存,但是实际上节点被绑到其它数据块上了,它远远不止sizeof(Cicle_List)字节的内存,因此在释放上就会存在内存溢出的错误。