指針和delete淺談


指針是一個很神奇的變量,在我看來,以指針為基礎,可以延伸出三個值。

1 指針的地址

2 指針的值

3 指針指向的值

有的人或許認為指針指向的值其實和指針本身並不是直接相關連的。

但是其實這個特性確實我們在編程中經常使用的,所以我就把他加了進來。

在介紹之前,如果您對這里已經足夠了解並且有興趣看看我說了什么,那么請跳過這一段~

什么是指針的地址?

指針的也是一個變量,在三十二位計算機中,指針占有四個字節的內存空間,正好可以指滿32位機中左右的內存單元。

所以,很自然的,指針也有一個屬於自己的地址。

如果你定義一個指針,比如這樣:

int *ip;//int pointer

那么獲取其地址的方式就是將ip視為一個普通變量,然后用取地址符獲取其地址:

cout<<&p<<endl;

這樣就在屏幕中打印出了這個指針變量在內存單元中的地址。

這個地址在該進程的生命周期中是不會改變的,因為指針本身只是一個常規變量。

什么是指針的值呢?

之前已經說了,指針是一個變量,是變量,都會存貯一個值。

那么如何查看一個指針的值呢?

我們可以這樣理解一下。

用上面已經定義的ip為例。

假設我已經定義了另一個變量:int temp;

使指針ip指向temp的表達式如下:

ip=&temp;

我們都知道&temp獲取的是temp的地址,那么從表達式就可以知道,其實,ip本身,就表示temp的地址,也就是ip的值。

所以,直接輸出就可以了

cout<<ip<<endl;

最后一個,也是用的比較多的,就是指針指向的值。

為了方便,還是用上面的ip和temp。

ip指向temp,那么獲取temp的值,就可以通過ip中存儲的地址值來獲取temp的值。

如果你學過匯編,那么這是一個很簡單的工作。

而在C語言中,這一過程將更加簡單,只要在指針前加一個'*'號,問題就輕松解決。

也就是說*p可以當成temp用。

當然,指針的用途不僅僅局限於此,指針還可以用於函數間數據的共享處理,以及開辟新的內存單元,調用函數,直接從某一出地址開始執行程序。

至於引用,我只能說C++中的引用就是一個只讀的指針,在參數傳遞的時候編譯器很聰明的做了一些讓開發者省力氣的工作,別的,我還真沒發現什么。

而至於講delete,就必須要講到new。

C++中的new的作用相當C中的malloc,顧名思義,即memory allcoc。

new用於內存分配和布局,功能強大,而且比malloc要簡練不少。

還是上面的那個指針,就可以通過這種方式為其開辟一小塊內存單元:

ip=new int;//如果是數組的話,加上[N]

這樣ip就獲取了一塊大小為int的內存單元。

如何清理呢?

這時就用到了delete。

操作也很簡單,只要將需要釋放的內存單元的指針放在delete后面就可以了

delete ip;

似乎到這里工作就已經結束了,但是昨天的一個隊列清除的函數讓我有了一個想法,而這個想法和delete有很大的關系。

如果我想要清除一個隊列,能不能只用隊列的頭指針呢?

如果delete只是返回一個記錄,將相應的內存空間返還給Os,而不修改其值的話,那么這種想法將是可能的。

所以我做了這樣的嘗試:

 

    int *p=new int;
    int t=10;
    p=t;
    cout<<&p<<endl
        <<*p<<endl
        <<p<<endl;
    delete p;
    cout<<&p<<endl
        <<*p<<endl
        <<p<<endl

  輸出結果截圖所示:

在這里可以發現,在經過delete之后,盡管指針的只沒有變,但是指向的內存空間的值已經跑飛了……

在結構體代碼測試的時候,也是如此。

代碼是這樣的:

 1 struct Ntemp *temp1=newNtemp;//struct Ntemp{int a;struct Ntemp *next;};
 2     temp1->a=320;
 3     temp1->next=new Ntemp;//the value of next is changed
 4     cout<<(int *)temp1<<endl;
 5     cout<<temp1->next<<endl;
 6     cout<<temp1->a<<endl;
 7     delete temp1;//delete it
 8     cout<<(int *)temp1<<endl;
 9     cout<<temp1->next<<endl;
10     cout<<temp1->a<<endl;

運行結果卻是這樣的:

可以發現,當temp1指向的內存空間被釋放掉后,temp1本身的值並沒有改變,而temp1的next指針的值卻發生了變化。

也就是說,next不再指向專門為其開辟的地址空間。

盡管temp1的地址值沒有變,但是其指向的內存空間的值,被改變了。

那是不是因為next指針不是原來的那塊空間呢?

這里我專門測試了一下,可以講上面的代碼進行一點點的修改,把第五行和第九行的本值輸出改為地址輸出。

你會發現,其值並沒有改變,而且地址相對於temp1的偏移量就是4個字節,一個int值的大小(就是a的空間)。

所以delete刪除一個結構體的時候,並不會修改指針本身的值,但會改寫其指向地址空間的值。

所以,單個指針清空隊列,是不可行的。

這里應該本篇已經到尾聲了,但是有一個很有意思的事情就是,每次程序的輸出后,next的低16位的值都是一樣的。

比如這個:

和上面的輸出結果對比,你會發現第五行的值是一樣的。

這個似乎表明,delete對於釋放后的地址空間,會進行統一的賦值操作。

至於為什么,我不是很清楚,在這就不隨便說自己的猜想了,如果有哪位大神知道,還望指導一二。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM