簡體   English   中英

刪除指向對象的C ++指針

[英]Deleting C++ pointers to an object

我以為刪除命令會釋放我分配的內存。 有人可以解釋為什么刪除后我似乎仍在使用內存嗎?

class Test
{
public:
    int time;
};

int main()
{
    Test *e;

    e = new Test;

    e->time = 1;
    cout << e->time << endl;

    delete e;

    e->time = 2;
    cout << e->time << endl;

    return(0);
}

我期望e-> time = 2后出現段故障;

謝謝!

我期望e-> time = 2后出現段故障;

您不應該“期望”任何事情; 您正在調用未定義的行為,根據定義,這是未定義的。 這意味着您不能再對程序的狀態做出任何合理的期望。

未定義的行為就是未定義的行為。 如果可以的話,它甚至可以工作。

當“刪除”內存時,基本上就是將分配的內存返回到堆中。 這僅表示用於組織堆內存的數據結構已更新,以指示該內存現在可供使用。 它沒有清除或類似的東西。 您正在訪問仍存在但屬於操作系統的內存。 這是未定義的行為。

編輯:

順便說一句,當您嘗試從沒有讀取權限的段中讀取內存時,就會發生段錯誤。 在平面內存模型中,這可能意味着您試圖讀取內核空間中的內存。 可能是因為您取消引用了錯誤的指針。

訪問已刪除的對象是未定義的行為。 什么都可能發生

取消引用指向已刪除對象的指針是未定義的。 該對象的內存可能尚未被覆蓋,因此您的對象仍然存在(如果可以使用的話)。

指針是內存中地址的容器。 您始終可以使用聲明的指針,但是除非將其初始化為您擁有的內存,否則會造成混亂甚至更糟。

Test *e;
e->time = 2;

也可以編譯,無法正常工作。 盡量減少此類混亂,因此:

{
  boost::scoped_ptr<Test> e(new Test);

  e->time = 1;
  cout << e->time << endl;

  e->time = 2;
  cout << e->time << endl;
}

不需要new/delete ,只需將花括號括起來以定義范圍,並使用適當的智能指針即可。

在valgrind下運行它。 它會告訴你你做了一件壞事

正如其他人所說,您所做的是錯誤的,但是您不能指望任何特定的行為。

在大多數現代系統上可能發生的情況是,為e分配和占用的內存在映射為對您的程序有效的內存頁面上,並且您delete d e並不會撤消該映射。

因此,您仍在訪問應用程序有權從OS使用的內存。 因此,沒有分割錯誤。 可能的,但是,如果有足夠的東西之間發生delete e和訪問內存頁面將被重新映射。 然后您會遇到段錯誤。

測試不中斷的原因是運氣好,而且您的例程非常簡單,很短。 您正在尋址仍在進程空間中的內存,並且指令很少,例程可能一次執行。

delete關鍵字在進程的內存管理器中取消分配內存,但是並不能清除內存或(通常)完全不使用它。 如果以后使用內存,則值將更改,但在那之前,最后設置的值將一直存在(或多或少,這畢竟是不確定的)。

考慮到您的例程只有幾條指令,因此處理器很有可能按順序執行它們,而沒有在其間切換到其他進程的可能性。 這樣做的副作用是,其他任何東西都不可能覆蓋或分配您的內存,因此內存保留在進程的空間中。

由於再次使用它的速度非常快,因此您留下的值(可能仍然)仍然存在,並且不太可能被其他進程使用。

暫無
暫無

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

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