[英]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.