c 中 delete的實質是什麼

時間 2022-02-05 06:10:05

1樓:匿名使用者

樓上的回答好像不太正確:

首先,delete p後,p仍然可用;

其次delete p不必和p=null連用。

delete用來釋放new所進行的操作,可以把delete所進行的操作看為new的你操作。int *p = new int;中的new的作用是為指標p賦「初始地址」的,如你的程式中p被賦予了0x00570738的首地址,此時p指向這塊記憶體。

也就是說new操作(new是操作符operator,不是函式)只是為了動態分配記憶體,建立new操作符的本意是為了delete,普通的指標賦值以後,如果不再使用,想要消除的話必須要等到它的固有生存期結束以後,這就會佔用機器資源。

delete操作也只是new的內操作,並不能刪除p,它只是把new得的內容釋放掉,防止記憶體洩漏。程式中使用new,而不使用delete釋放自己分配的記憶體會引起系統可以使用的記憶體數量不斷減少。如果你的程式是一個不斷執行的伺服器的話,那麼最終你的系統會因為沒有足夠的虛擬記憶體而要崩潰!

但是隻要你關閉那個洩漏記憶體的程式那麼它沒有釋放的記憶體自動會釋放。

delete p;包含了p=unll操作,此時*p=0(because p=null).很明顯delete並不是真的把變數p給銷燬了(p的生存期沒有結束),而是釋放它所指向的記憶體(節省機器資源),delete後的p還是一個整形指標,只不過此時的*p=0罷了。

2樓:海濤大興

首先申明:指標也是一種變數,它自己也有一塊儲存空間,用於存放它指向的其他變數的地址。

你的**中「 cout <<"p所指向空間的大小"<< *p <

「cout <<"p的指向"<< p <

前面「int * p = new int ;」給指標p分配了一塊空間(不是它自己的),delete p;之後,釋放了p所指向的空間。你用「*p=9;」系統就有分配了一塊空間來存放9這個數字,然後讓p指向它。

p的地址是不會變的,除非者個函式結束,p自己的空間才被釋放,者就是「區域性變數」。用new分配的空間,不是區域性變數,函式結束後不會被釋放,必須用delete釋放,否則出現「記憶體洩漏」。

3樓:匿名使用者

delete 是c++中釋放記憶體的運算子

1)c++程式設計師需要自己維護堆的記憶體;

2)堆的空間遠大於棧,棧是系統自己維護的;

3)堆中申請記憶體是用new;

4)delete是專門用來釋放用new申請的物件或者記憶體的。

4樓:匿名使用者

delete 只完成釋放前面申請的堆記憶體空間的工作,你是對的,釋放空間後,地址是永遠都不變的,只是空間被釋放,程式關閉後,地址才會被收回。

5樓:匿名使用者

delete 只是刪除了程式中的定義而已 要改變p的指向需要在程式中重新定義

由於c++的記憶體分配是需要程式設計師自己來管理、控制的所以在重新定義指標前是不會改變的

6樓:

p指向一塊記憶體

delete p 釋放這塊記憶體

p此時是不可用的,

一般delete p要和p=null連用

delete是對free的封裝

對應的是new,new是molloc的封裝這是我的理解,如果誤人子弟了,大家儘快告訴我

7樓:

delete之後,下次再重新申請的時候可以再申請這塊記憶體地址,也就是將這塊地址放到了空閒連結串列上,對於這塊地址的內容,沒有進行清空處理(也沒有必要);由於你沒有將p賦為null,所以p指標還是指向這塊記憶體空間。

如果不delete的話,你這塊記憶體是不能在申請使用的,也就是所謂的記憶體洩露。

對於delete之後的指標p,此時是「野指標」。

一般的正確做法是:

int * p = new int ;

if (p == null)(千萬不要忘了這句話!!!)delete p;

p = null;(千萬不要忘了這一句話!!)上面所說的,希望能理解……

8樓:匿名使用者

首先new是new在堆上的,在delete之後會釋放掉,但是編譯器不一定在delete之後將p清空,所以你這裡p還是指向原來的位置,但是這個位置一旦有new給其他變數,那麼就是不可控的了。

你嘗試下面的**

#include

int main()

c++ delete命令的原理是什麼?

9樓:匿名使用者

關於這個問題。我前幾天剛好在 effective c++裡看到。

這種問題牽扯到 虛解構函式。

大概是這樣的:

比如a*p=new b;

。。。delete p;

如果父類的 解構函式不是一個虛擬函式 。那麼delete p這樣的行為是不可**的——無法知道將會發生什麼。

c++語言標準關於這個問題的闡述非常清楚:當通過基類的指標去刪除派生類的物件,而基類又沒有虛解構函式時,結果將是不可確定的(實際執行時經常發生的是,派生類的解構函式永遠不會被呼叫。)

為了避免這個問題,只需要使a的解構函式為virtual。宣告解構函式為虛就會帶來你所希望的執行良好的行為:物件記憶體釋放時,a和b的解構函式都會被呼叫。

關於第二個問題 delete p只是釋放指標指向的記憶體所儲存的資料,並不會改變指標所儲存的地址。因此執行完這個操作可以

設定p=null

我執行了delete p,cout<

10樓:

我們編譯出來的程式執行時是和作業系統打交道的,程式中用到的記憶體都向作業系統申請,在多工的作業系統下,不允許普通的程式訪問未分配的記憶體。

作業系統手裡有一張表,標明記憶體中的哪些單元被哪個程式佔用了,哪些是空閒的(空閒不一定是空值,我們編寫的程式如果動態變數沒有初始化往往會帶有不定值,就是這個緣故),當程式提出申請,它就把空閒的記憶體分配給程式。程式執行完後作業系統再把分配給的記憶體標記為空閒,以供其他程式用。

其實我們完全留意到,向磁碟寫東西的時候很慢,但把寫進了的東西刪掉的時候卻快得多,原因就在於作業系統刪除檔案的時候偷懶了,並沒有徹底粉碎檔案的每一個資料,而是在那張檔案分配表上將這個檔案所在的區域標記為空閒罷了,多數資料仍然在那裡,從而給資料恢復軟體留下了後門。

樓主的程式前面會申請空間來存放類a和b的物件。執行到delete就會去記憶體的堆區將指定的記憶體單元交還給作業系統。所以必須和new配套使用,否則會釀成嚴重後果。

我個人的猜測,執行delete只是將它後面變數的地址告訴給作業系統,作業系統把它手裡的那張表給改了,但delete掉的指標沒有變化,還是原來指向的變數的地址值。可以執行一下這個小程式:

#include

int main(void)

可以看到,delete前後,指標p的值沒有變化。但是如果將2處改為cout<<*p;就要出問題了,作業系統會阻止程式去訪問這個地址(表現為訪問衝突,access violation),因為這個地址已經用delete歸還給作業系統了。這時候的指標p叫做懸空狀態,也就是野指標,怎麼稱呼都無所謂。

它並沒有被銷燬,通過重新取其他變數的地址,還可以繼續訪問*p,但現在不行。

指標實際上是一個無符號整型變數,幾乎所有我們碰到的指標,在c++下都是4個位元組,因為c++在32位機上將int實現得和long int一樣大小。

那麼為什麼要給指標規定型別呢?我猜測,這一方面是為了訪問它指向的物件時確定讀取記憶體單元的長度,比如char型變數佔1個位元組,int型變數佔4個位元組,類物件和結構體物件佔的長度更加多樣化,當定義了一個char型指標p,執行*p時程式只讀取一個位元組的內容,如果p是int型則*p讀取4個連續的位元組的內容。還有指標相加減,指標自增自減運算,都可以通過這個來確定一次移動的長度。

另一方面,也防止亂指發生意外吧,c語言中printf和scanf的格式控制串就要用的時候親自設定,如果設不對執行時就可能出錯。

11樓:匿名使用者

首先sizeof並不是萬能的,你用sizeof來看大小本來就是錯的,用錯的東西來解釋其它東西,結果肯定是錯的

c中可以用delete釋放陣列的空間嗎

這樣定義陣列的話是在棧上分配記憶體,超過作用域範圍的時候會自動釋放掉,使用new操作符分配的記憶體,是在堆上,需要使用delete釋放,因此如果像你那樣定義陣列的話,不必釋放記憶體 用delete釋放的只能是用new動態分配的陣列空間,若陣列不是動態分配的則不能用delete釋放。舉兩個例子詳細說明...

火的實質是什麼,管理的實質是什麼

火就是一種物質,屬於等離子體。等離子體是由部分電子被剝奪後的原子及原子被電離後產生的正負電子組成的離子化氣體狀物質,它是除去固 液 氣外,物質存在的第四態。等離子體是一種很好的導電體,利用經過巧妙設計的磁場可以捕捉 移動和加速等離子體。等離子體物理的發展為材料 能源 資訊 環境空間,空間物理,地球物...

解構函式中delete的問題

保晏然 解構函式中應該是這樣 假設char 變數名是str if str null deletestr 因為你是在成員函式中new的,有可能在你銷燬物件時str並沒有分配記憶體,而你卻檢視釋放它指向的記憶體,當然會出錯。加上if判斷後就可以避免這種情況。 燃燒的左眼 建構函式中都初始化為0了?首先指...