簡體   English   中英

關於與free()一起使用時指針與數組表示法之間的區別

[英]On the difference between pointer and array notation when used with free()

並且,歡迎回到另一個有趣的小故事,“有趣的小矮人問 (可能) 愚蠢的問題”。

我為K&R的練習1-16使用動態內存分配編寫了一個解決方案。 作為檢查工作的一部分,我通過Valgrind運行了代碼。 Valgrind報告了一些內存泄漏,盡管我的1:1 malloc:free比率(令人困惑)。 經過大量的擺弄和閱讀GNU c lib手冊 Valgrind用戶手冊 ,我最終來到SO。 我讀過的所有帖子都沒有真正解決我的問題,直到我注意到一些其他無關問題的解決方案,這些解決方案使用一種表示法可以表示為以下等價形式:

*(dbl_ptr + i) == dbl_ptr[i]

其中dbl_ptr的類型為char**i的類型為int

在我自己的原始代碼中,我一直試圖通過以下方式free()一個雙指針:

for( i = 0 ; i < count ; ++i ) {
   free( (dbl_ptr + i) );     //Valgrind complains about a leak right here
}

free( dbl_ptr );

但是當我用這些行重新編譯程序時:

for( i = 0 ; i < count ; ++i ) {
    free( dbl_ptr[i] );    //No more Valgrind complaints
}

free( dbl_ptr );

然后該程序被報告為內存安全。 為什么?

幫助我理解,仁慈和仁慈的StackOverlords!

結尾:

如果您想對這里發生的事情有深入的了解,我建議閱讀templatetypedef對這篇文章的回答。 我不相信我可以在自己的代碼中寫出關於錯誤原因的更好的解釋。 事實證明,我的錯誤是關於free()如何解釋參數的誤解,以及對C語言中數組語法背后的語義的根本無知。

快速又骯臟: dbl_ptr[i]隱式取消引用dbl_ptr + i

調用free ,參數應為指向要取消分配的內存塊前端的指針。

因此,假設您有一個double*數組。 該數組如下所示:

  dbl_ptr ---> [ 0 ][ 1 ][ 2 ] ... [ k ]
                 |    |    |         |
                 v    v    v         v
                arr  arr  arr       arr

現在,假設您打電話

free(dbl_ptr + i);

以圖形方式, dbl_ptr + i指向此處(讓我們選擇i = 1

  dbl_ptr + i --------+
                      |
                      v
  dbl_ptr ---> [ 0 ][ 1 ][ 2 ] ... [ k ]
                 |    |    |         |
                 v    v    v         v
                arr  arr  arr       arr

因此, free將此調用解釋為您要從分配給dbl_ptr的內存塊的中間而不是從dbl_ptr[i]指向的內存塊中釋放某些內容。 這是一個問題,因為您不能使用指向內存塊中間的指針來進行free調用。

另一方面,打電話

free(*(dbl_ptr + i));

要么

free(dbl_ptr[i]);

那么您實際上是在說要釋放由dbl_ptr指向的數組的第i個元素所指向的dbl_ptr

您忘記了在

free( (dbl_ptr + i) );   

它應該是

free( *(dbl_ptr + i) ); 

free釋放由指針參數指向的內存。 在正確的情況下, free(dbl_ptr[i])會從數組中查找指針,然后釋放其指向的內存。 在不正確的情況下, free( (dbl_ptr + i))傳遞給它的指針實際上是指向數組中某個位置的指針,指向您要釋放的內存的指針。

為了輕松查看差異,請考慮i = 0的情況。 正確的版本是free(dbl_ptr[0]) 不正確的版本是free(dbl_ptr+0) ,與free(dbl_ptr)相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM