標籤:

c++delete一個指針,沒有賦值為null,再創建同類型的指針,有沒有可能被釋放資源的內存地址被重新使用,賦值給新指針?如何用程序驗證這種可能性?這個class里有成員是引用,引用所指的內存也會被釋放嗎?


對第一個問題,會。

while(1){
A* ptr = new A(); // 一直執行這段代碼,ptr有很大可能會出現之前出現過的地址。
delete ptr;
}

不要說同類型,即便是不同類型,在反覆的創建釋放中,也有可能被分配到同一個地址,而且這和你有沒有把指針賦值為NULL無關。

尤其是小對象,因為現代內存分配器都是池化的,會最大限度的復用內存。

所以沒有把握的時候,別用地址作為Map的Index。

第二個問題,不會。引用並沒有被引用對象的所有權,這一點和指針是相同的。


如果我沒有理解錯的話,你的想法(就某個新對象創建在一個舊對象的位置)是可以的

參考

#include &

#include &

using namespace std;

int main()

{

int* p1 = new int;

int* p2 = new(p1) int;

cout&<&

delete p2;

return 0;

}

第二個問題,

不會,試想一下,又不是他創建的,為什麼讓他銷毀?憑什麼讓他銷毀?

萬一這個成員對象其他地方還在使用呢?


UAF呀,漏洞就是這麼用的。


就那麼點虛擬內存地址空間,當然會遇到同一個地址啊


已釋放內存的重新分配是經典的ABA問題之一。

會不會遇到主要取決於malloc實現,tcmalloc肯定會復用,ptmalloc不是太確定,但是它有arena,應該也是會復用內存的,不然頻繁觸發page fault,會帶來不必要的性能損耗。

驗證很簡單,不停new delete小內存,把地址存到某個set裡面,看看會不會有重複就可以了


有可能,就是因為這個原因,用指針作為 handle 的程序常常死的很慘。

不過這跟是否將指針賦值為 null 沒什麼關係,這隻跟內存分配器策略有關係。


隨手一試就有好多重複的

第二個問題其他答案也說的很清楚了,引用本質是別名,編譯好之後引用就沒啦!


什麼叫「創建同類型的指針」,聽著好彆扭,是創建同類型對象吧。新的對象與以前對象佔用同一片內存空間這種情況是可能出現的。ABA問題就包含這一情況。delete後指針是否賦值為null,只是與該指針是否wild有關,與創建新對象沒有任何關係。

驗證的話,不一定會出現,只能不斷new去嘗試了。

最後一個指針和引用是不同的概念,如果是成員是指針並指向了分配好的內存空間,需要手動釋放內存,這正是析構函數要做的工作之一。


針對第一個問題空明流轉的方法就很好。

引用不佔內存空間何來釋放之說?


c++delete一個指針,沒有賦值為null,再創建同類型的指針,有沒有可能被釋放資源的內存地址被重新使用,賦值給新指針?

//這個會啊,不然物理內存怎麼夠用,

如何用程序驗證這種可能性?

//記錄每次分配的地址,然後找交集。

這個class里有成員是引用,引用所指的內存也會被釋放嗎?

//C++是沒有GC機制的語言。

//通常來說,不會。

//如果會,那麼意味著內存會被複用,對於應用,這是致命的。

//同時也意味著內存泄露變得不確定性。

//這個涉及到各個版本C++對內存管理的實現,因操作系統、語言版本不同而不同。

------------------

2015-08-05:update了一下,貌似我之前的回答會產生誤解。


推薦閱讀:

如何評價C++17中的新特性fold expression?
C++有右值引用以後是否可以直接return 字元串、結構體而無需考慮大量數據複製的性能問題了?
C++ 研發實習生面試通常會被問到什麼問題?
怎麼返回容器中部分內容的引用?

TAG:C |