記錄一次C語言中free(p)失敗

為天健湖代言 2021-09-18 10:51:42 阅读数:579

一次 言中 free

首先介紹一下自己的程序出錯的原因,然後總結一下什麼時候free會失敗。

1.程序偽代碼

// 已知payload已經指向一部分內存數據
char * payload;
int payload_len; //payload的長度
char * front_pkt="xxxxxxxxx";
// 申請內存
char * temp_ptr=(char *); malloc(payload_len+strlen(front_pkt)+1);// 多申請一比特放\0
memset(temp_ptr,0,payload_len+strlen(front_pkt)+1);
// 拷貝
strcat(temp_ptr,front_pkt);
strcat(temp_ptr,payload); // 錯誤原因就發生在這裏
...
// 釋放
free(temp_ptr);//報錯的地方

定比特過程:

由於是和別的程序聯調,首先定比特出事free()函數時報的錯。然後就開始從為指針申請內存的地方開始定比特,最後發現,在strcat(temp_ptr,payload)之後,指針temp_ptr指向的數據竟然比我申請的內存要大,尾部有一部分雜數據。至此,發現是內存越界了。

為什麼會越界呢?因為payload並不能保證是字符串,即不能保證是符號'\0'結尾的。在使用strcat追加拷貝字符串時是根據'\0'符號來判斷拷貝結束的。所以非常有可能發生內存越界的行為。

修改方案:使用strncat()函數,指定拷貝的長度。

定比特心得:

1.在使用C語言的字符串函數時,str開頭的,一定要確保指針指向的內存是字符串,即'\0'結尾。

2.盡量使用帶n的函數,指定內存、字符串拷貝等的長度,可以避免不必要的麻煩。

總結:什麼時候free(p)會報錯?

1.如果p不是NULL指針,對p連續操作兩次就導致程序運行錯誤

2.內存越界,指針初始值被修改掉,和別的區塊內存重疊,分配的這段內存的“門牌號”被改掉了,free就會失敗。比如上邊的例子。

引申:free的原理

free(p)釋放p指向的內存時,並不需要提供要釋放內存的大小,這是因為在p附近的某個比特置存放有維護該內存區域的數據,這是由內存申請函數malloc等產生的。實際上在p之前有個結構體,記錄了該塊內存的信息。如果程序因為內存越界修改了結構體,則會導致free()函數報錯返回,並不釋放任何內存。

以上邊的例子,strcat(temp_ptr,payload),向申請的內存中拷貝了過多的數據。

 

注:由於知識有限,本文所講必定有缺陷之處,請謹慎參考,如有錯誤,歡迎批評指正!

版权声明:本文为[為天健湖代言]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918105142103m.html