[英]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.