2011-03-22 162 views
4

我的問題很簡單。我們通常通過聲明一個指針然後爲該指針分配一塊內存來分配內存。假設某處代碼,我碰巧使用分配和釋放內存

ptr = ptr + 1

,然後我用

free(ptr)

誰能告訴會發生什麼。整個內存塊將被釋放或其他東西。我可以部分釋放內存嗎?

回答

7

必須始終通過相同的指針正好free你從malloc得到(或realloc)。如果你不這樣做,「行爲是不確定的」,這是一個技術術語,這意味着你可以」不依靠程序以任何可預測的方式行事。不過,在這種情況下,您應該期望它立即崩潰。 (如果運氣不好,它會損壞內存,導致一段時間後崩潰,或者更糟糕的是,輸出不正確。)

部分釋放內存的唯一方法是使用較小尺寸的realloc,但這隻適用於修剪最後,並不能保證將修剪過的塊用於其他分配。

1

這是不可能的釋放部分內存塊。你唯一能做的就是重新分配給它不同大小的塊。然而,這並不能保證塊會落入內存中的相同位置(它可能會複製到其他地方)。

1

您必須傳遞給free()指向返回的相同位置malloc()的指針。這是因爲分配器保留了你分配的塊的列表(@everyone:如果我錯了,隨意添加/修改),如果你傳遞給free的指針不會比較它的列表free()抱怨( 「壞記憶塊」也許?)。爲了部分釋放內存,你應該使用realloc(),它會改變該塊內存的大小,但是速度慢並且效率低下。只有在確定新的區塊大小或留出更多空間以填補未來時,才應該使用它。

+0

因此,你的意思是分配器保留一個列表,並釋放整個塊,如果我們釋放一個包含該塊第一個字節地址的指針? – bubble 2011-03-22 15:27:34

+0

@bubble這是如何得到2 upvotes?從什麼時候開始將指針傳遞給malloc? – 2011-03-22 15:30:46

+0

@bubble:是的,它記得你爲每個塊分配了多少個字節 – BlackBear 2011-03-22 15:31:05

1

malloc(),free()和realloc()不是C語言的一部分。

這些是在標準庫中定義的函數。處理它的標準庫中的代碼通常稱爲「分配器」。所以,實際答案是「這取決於C庫」。

在Linux上,glibc會使程序崩潰。 在VC++上,C運行時會破壞分配器的狀態

源代碼可用於這些庫,因此您可以實際將斷點和步驟放入空閒位置。

+1

調用標準C庫「不是[C]語言的一部分」不是錯誤的*,但會讓我感到不適當的細分頭髮。 – zwol 2011-03-23 19:06:53

+0

不將其稱爲C語言一部分的原因是因爲您可以通過唱一個不同的庫(使用相同的編譯器)或編寫自己的malloc/free代碼來自定義行爲。我曾經在98 - 99年左右這樣做過。這會給您帶來諸多好處,例如編寫一個版本,可以在調試器中打印出所有已分配塊的列表。 – 2011-03-24 03:37:08