2010-08-17 84 views
5

它實際上在某些編譯器/機器上工作,但在其他編譯器/機器上它會導致堆損壞和崩潰?爲什麼在分配'new'的指針上調用free()會導致堆損壞?

有沒有人有任何深入瞭解底下發生的事情?

+0

你會得到未定義的行爲,現在和永遠。 [不要這樣做。](http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.3) – GManNickG 2010-08-17 18:49:40

+8

他問你爲什麼會這樣做,只是告訴他不要做這無助於他進一步理解任何事情。 – bobDevil 2010-08-17 18:52:16

+1

@bobDevil:好的,C++標準沒有定義這種行爲,這意味着語言實現者不會想要施加合理的行爲。沒有傳統的行爲(除了「不這樣做!」),所以甚至沒有一個非正式的標準。經驗上,這種行爲似乎有所不同。因此,你不能指望任何特定的行爲,也沒有編譯器工程師會給你任何同情。這足以說明「不要這樣做!」而不會解釋爲何發生任何特定行爲。 – 2010-08-17 19:02:30

回答

17

當您使用delete時,C++想要調用對象上的析構函數,但將它傳遞給free不允許發生這種情況。如果對象包含其他對象,那麼這些對象的析構函數也不會被調用。如果對象中有指針,那麼這些指針就不會被釋放。

另外,C++的newdelete實際上可以從malloc要求較大的內存量和使用記賬額外的(如存儲的析構函數的地址),所以你傳遞給free指針不會實際上是一個那是malloc編。

2

標準說,你一定要配合完美的分配/釋放功能(new - deletenew[] - delete[]malloc - free)。理論上,一些編譯器很有可能將operator new()作爲簡單的malloc()執行,所以它不會導致崩潰,而是「僅」跳過析構函數調用(這本身很糟糕)。但是,operator[]可能會在分配的內存塊中存儲元素的數量,在這種情況下,new[]返回的地址指向由malloc()(而不是開頭)分配的某個塊內,這意味着您不能使用free()釋放它。

2

新的操作符也是可重載的。如果有人寫了一個完全不同的新操作符,比如說從內存池中獲取指針,那麼在這些指針上釋放可能是非常危險的。

+1

...在這些指針上調用'free' ... – Potatoswatter 2010-08-17 21:37:55

相關問題