2015-01-10 20 views
-3

INT主() {對準的存儲器不被_aligned_free功能釋放

  1. INT *對準;

    //對準值0xcccccccc {???}

  2. 對準=(INT *)_ aligned_malloc(的sizeof(int)的* 1000,16);

    //對準值0x001d9490 {-842150451}

  3. _aligned_free(對準);

    ////對準值0x001d9490 {-17891602}地址並沒有改變

  4. *對齊== 100;

  5. int * y;

    // Y值0xcccccccc {???}

  6. Y = INT新();

    // Y值0x001d9480 {0}

  7. 刪除(Y);

    // Y值0x00008123 {???}地址已經改變

  8. * Y = 100; //給出例外

}

我的問題:

爲什麼在第4行代碼不給例外?這是否意味着_aligned_free沒有正確釋放內存?如果是,那麼我們應該如何釋放由_aligned_malloc分配的內存。

+0

在情況1和5中,您正在讀取未初始化的值,這是一個錯誤。在情況4和8中,你正在從你釋放的記憶中讀取,這是一個錯誤。對於「爲什麼沒有錯誤的代碼做我所期望的」的通用答案是「這就是爲什麼我們修復錯誤,錯誤代碼沒有達到預期的程度,修復錯誤並且代碼將完成您的工作期望」。 –

+0

謝謝大衛。我明白了這些是應該修復的錯誤。我對這個問題的意圖是爲什麼內存指向對齊(在_aligned_free之後)未被設置爲無效內存,而在y(在刪除之後)的情況下。它看起來對我來說(在閱讀註釋之後)更多類型的編譯器或堆釋放器的東西。我只是想確認一下。而已。 – coder

回答

0

第4行的代碼沒有做任何事 - 您正在使用==(測試等同性)而不是=(作業)。嗯,實際上,它做的事情 - 它會嘗試讀取從您剛剛釋放的內存塊中的地址(並將該值與100進行比較)。這可能不一定會導致異常 - 許多堆管理器將從您的進程地址空間中分配的較大塊中分割塊,因此釋放一塊可能很好,只需將該塊標記爲可供堆管理器重用即可。在釋放後讀取/寫入此空間可能不會每次都會導致異常(因爲它可能仍然是該進程的有效堆空間的一部分),但這肯定是一個錯誤。

另外,在調用_aligned_free之後,指針值(aligned)不應該改變 - 這並不意味着內存未被釋放。

+0

謝謝Frasnian。我知道如果沒有例外,內存將總是被_aligned_free釋放。 – coder

0

int * aligned;

//對準值0xcccccccc {} ???

你沒有初始化指針,所以它有任何價值的垃圾在那裏main開始之前。如果你想讓它從零開始,請執行int *aligned = NULL;

aligned =(int *)_ aligned_malloc(sizeof(int)* 1000,16);

//對準值0x001d9490 {-842150451}

看起來行

_aligned_free(對準);

////對準值0x001d9490 {} -17891602地址並沒有改變

儘管如此free電話改變了傳遞的指針。永遠。

* aligned == 100;

正如frasnian指出的那樣,這會做一個比較並將結果拋棄。但即使您將其更改爲賦值,您也會取消引用已釋放的指針,這是未定義的行爲。這意味着任何事情都可能發生:它可以工作,可能會崩潰,它可能會做一些意想不到的事情。

int * y;

// Y值0xcccccccc {???}

同樣,未初始化。

y = new int();

// Y值0x001d9480 {0}

好,您有一個指向int

delete(y);

// Y值0x00008123 {} ???地址發生了變化

這是意想不到的。可能是你的編譯器的一個功能。可能是一個優化重用寄存器。

* y = 100; //異常

因爲您取消了一個已刪除的指針,並且您還處於未定義的行爲狀態。顯然你的平臺不喜歡整數的奇數地址。並非所有平臺都會在此處引發異常


的規則是,你傳遞給freedelete指針走了。死。前指針。推高位雛菊。爲峽灣祈禱。沒有更多。

寄存器中可能存在一個值,但它不再有效,不應使用。編譯器不能期望捕獲你嘗試使用死指針的情況。