簡體   English   中英

C ++:動態分配的變量未在Clang中刪除

[英]C++: Dynamically allocated variables not deleted in Clang

沃爾特·薩維奇(Walter Savitch)的``用C ++解決問題,第9版''指出第517頁:

當將delete應用於指針變量時,指向的動態變量將被銷毀。 那時,指針變量的值是不確定的,這意味着您不知道它指向的位置,也不知道它指向的位置。 而且,如果某個其他指針變量指向已被破壞的動態變量,則該另一個指針變量也是未定義的。

但是,在clang-902.0.39.1 ,刪除指針似乎並不妨礙我使用變量的能力。 這是演示此行為的簡短示例:

int *p1, *p2;
p1 = new int(3);
p2 = p1;

cout << *p1 << endl << *p2 << endl;

delete p1;

cout << *p1 << endl << *p2 << endl;

使用此代碼,我在單獨的行上有4 3 s的輸出。 我希望在delete p1;之后引用p1p2時會發生錯誤delete p1; ,我不應該嗎?

在Visual Studio的C ++編譯器下,引用p2輸出一個很大的負數,表示我們正在引用不屬於我們的內存,訪問p1會導致程序崩潰。

我希望刪除p1后引用p1和p2時會發生錯誤;不是嗎?

不必要。

此時,指針變量的值未定義

未定義(例如,在調用delete后使用指針)可能會導致發生任何事情,無論好壞,中立。

不需要編譯器為進一步使用指針設置任何運行時障礙。 特別是,不需要立即結束程序。 當然,如果編譯器(使用正確的設置)看到您的代碼正在重新使用已刪除的指針,則可能會向您發出警告。

在Visual Studio的C ++編譯器下,引用p2會輸出一個很大的負數,表示我們正在引用不屬於我們的內存,訪問p1會導致程序崩潰。

特定的編譯器可能會創建一個進程,該進程在特定的操作系統上,特定的內存負載條件下會導致崩潰。 否則可能不會。 同樣,不要求與指針關聯的內存中填充垃圾數據。

特別是,我相信調試版本中的Visual Studio可以檢測指針的內存,以便進一步使用會導致崩潰/異常。 這對於可調試性很有用。

除了調試版本,唯一可能導致的問題是偶然的。 對於調用了delete然后再使用的指針,請考慮以下可能性:

  • 該過程已將內存釋放到操作系統。 您的程序現在正嘗試訪問它無權訪問的內存。 SEGFAULT (崩潰)。
  • 在內部,該內存已被標記為屬於另一個變量(即程序的其他部分,稱為new或類似變量),並已被寫入。 它可能看起來充滿了垃圾數據。 根據您的程序如何使用變量,可能存在問題,也可能沒有問題。 它可能會崩潰,它可能會打印出亂碼等。
  • 在內部,內存被標記為已刪除,但是程序的其他部分均不需要它。 此刻,內存保持不變。 這大概是您在clang下看到的。

簡而言之,盡管預測刪除的指針將對存儲器產生什么影響是棘手的,但賦予程序員的唯一責任是:不再使用它。

當您刪除指針時該內存仍然存在,並且指針仍指向它。 但是,您無法保證它仍然有效或將來仍然存在。 內存分配(new / malloc / etc)已將該內存中的位置標記為不再使用,因此它可能會重新分配它或釋放頁面上的所有內存,這時訪問它會導致訪問沖突(段錯誤)。

例如,如果我使用指針創建三個新的int,它們很可能會在內存中彼此相鄰放置。 如果刪除中間指針,則該指針的地址仍然有效,因為在該頁面的所有內存不再有效之前,無法釋放內存頁面。 但是,即使我可以訪問已刪除指針的內存,也不能。 那是因為如果我創建一個新的int指針,它很可能會分配給該新位置。

BAD METAPHOR:記憶就像教室里的座位。 有些人需要更多的座位(或抬起腳或放下書包),而有些人則需要更少的座位。 您必須先騰出教室中的所有席位,然后才能將教室從學校中刪除。 如果您要求分配一個座位,您可能會獲得1號室,2號室。 如果放棄該座位(例如刪除指針),即使它不再屬於您,您仍然可以引用room1 / seat2。 如果您嘗試坐在里面,可能會發現有人已經被分配了。 如果您確實坐在椅子上,教室可能會在任何時候關閉,因為您說座位已經做完了。

座位=指針所指向的內存

教室=內存頁

您的指針仍指向舊位置,只是該內存不再屬於它們。 稍后可能會有另一個數據。 因此它不是穩定的輸出。

內存已被釋放,但是您的指針仍指向數據曾經所在的位置。

暫無
暫無

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

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