delete指針之後應賦值爲NULL——QT deletelater指針之後也一樣要立刻賦值爲NULL

delete p後,只是釋放了指針指向的內存空間。p並不會自動被置爲NULL,並且指針還在,同時還指向了以前的地址html

delete NULL編譯器不會報錯由於delete空指針是合法的)ios

例:面試

對一個非空指針delete後,若沒有賦NULL,若再次delete的話,有可能出現問題。安全

以下代碼socket

int *p = new int(3);函數

delete p;ui

delete p;this

用VC編譯運行將出現問題。spa

將其改成:.net

int *p = new int(3);

delete p;

p = NULL;

delete p;

則不會出現問題(由於delete空指針是合法的)。

轉自:http://blog.csdn.net/hudfang/article/details/43054243

 

具體的詳細緣由看下面的例子:

《delete一個指針以後,要記得設置爲NULL  》 

 衆所周知,最開始咱們用new來建立一個指針,那麼等咱們用完它以後,必定要用delete將該指針刪掉。可是,值得注意的是,難道就僅僅是刪除這個指針這麼簡單的麼?下面,咱們用一個程序來講明這個問題:

 1 #include <iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     int *p=new int;
 6     *p=3;
 7     cout<<"將3賦給p的地址後,指針p讀取的值:"<<*p<<endl;
 8     delete p;
 9     cout<<"刪除空間後,指針p讀取的值:"<<*p<<endl;
10     long *p1=new long;
11     *p1=100;
12     cout<<"建立新空間後,指針p中保存的地址:"<<p<<endl;
13     cout<<"指向新空間的指針p1保存的地址:"<<p1<<endl;
14     *p=23;
15     cout<<"將23賦給p的地址後,指針p讀取的值:"<<*p<<endl;
16     cout<<"將23賦給p的地址後,指針p1讀取的值:"<<*p1<<endl;
17     delete p1;
18     return 0;
19 }

在上面這個程序中,咱們在第8行就將指針p利用delete刪掉了。可是,咱們來看看程序的輸出結果:

      對照着上面的程序,咱們來分析一下這個輸出。首先,咱們在程序的第5行初始化了一個指針p。以後輸出指針p讀取的值。因爲第6行的緣由,程序確定會輸出3了。以後,咱們在程序的第8行刪除了這個指針p。可是咱們驚奇的發現,在程序的第9行居然能夠輸出指針p讀取的值。咱們不是已經把它刪了麼?其實否則,debug,上圖:

      從監視窗口中,咱們能夠看見雖然程序的第8行已經將指針p刪除了,可是在監視窗口中p仍然存在,只是*p所指向的值再也不是原來的3了,而是一個隨機數。這裏就說明了一個很是重要的概念:咱們在刪除一個指針以後,編譯器只會釋放該指針所指向的內存空間,而不會刪除這個指針自己。

      而後咱們接着往下分析。在程序的第10行咱們又建立了一個long型的指針p1。在12行與13行的輸出中咱們驚奇地發現,指針p保存的地址竟然和指針p1保存的地址如出一轍!這個就說明了指針p和指針p1都指向內存的同一個地方!!!出現這種情況的緣由實際上是因爲編譯器。編譯器默認將釋放掉的內存空間回收而後分配給新開闢的空間。因此在第11行因爲咱們新開闢了一個能夠保存long型變量的空間而且由p1來指向它,那麼這裏的p1指向的其實就是在程序第8行釋放掉的內存空間,即p指向的內存空間!因此,這就致使了兩個指針同時指向同一個內存空間。這是多不安全的一件事情啊!要知道,咱們是把指針p刪了的啊!若是再從新對*p進行賦值操做,那麼不是會連着*p1一塊兒改動麼?

      果真,讓咱們擔憂的事情出現了。咱們明明在程序的第11行中定義了*p1的值爲100,可是在輸出上面,指針p1讀取的值居然也是23。這個緣由就是由於野指針p形成的。咱們能夠看到,在程序的第14行咱們將23賦給了*p。又因爲p和p1指向的是同一塊內存單元,因此在這裏至關於也將p1所指向的內存單元中的值(原來是100),改爲了23!這樣必然會致使程序的出錯!

       那麼咱們就不由要問了,對於這種因爲野指針形成的問題,有沒有解決的方法呢?答案固然是有的了。咱們只須要牢記下面這句話:

在刪除一個指針以後,必定將該指針設置成空指針(即在delete *p以後必定要加上: p=NULL)

      咱們來看一下在stdio.h中關於關鍵字NULL的定義:

/* Define NULL pointer value */
 
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

注意上面定義的第5行。這裏其實就說明了NULL就是0。也就是說,咱們在刪除完指針p以後,必定要把它變成空指針!只有這樣,纔會杜絕上面程序中出現的野指針的錯誤。

p.s. 對於NULL的應用,咱們不該該僅限於上面的方法,還能夠應用NULL來判斷指針是否初始化成功了,以下例if中的判斷方法:

#include <iostream>
using namespace std;
 
int main()
{
    int *p=new int;
    if (p==NULL)
    {
        //判斷指針p是否是空指針,若是是空指針,那麼程序在這裏就應該報錯
        //報錯的方法有不少,好比說返回一個ERROR值:
        //return ERROR;
    }
 
    //判斷了操做成功以後咱們才能進行一系列的操做
    //...
 
    //用完指針p以後,必定要將其刪掉。這樣能夠杜絕野指針的存在
    delete p;
    //刪除指針p以後,必定要加上下面這句話,省得成爲野指針
    p=NULL;
}

好了,下次必定要記住,在分配空間給指針以後,必定要用NULL來判斷一下是否成功了。而後在刪除這個指針的時候,也要用NULL來賦給指針,杜絕成爲野指針!

O(∩_∩)O哈哈~寫完,收工~~~~

轉自:http://www.cnblogs.com/uniqueliu/archive/2011/07/18/2109778.html#

 

《對指針調用deletelater()後能當即將指針賦值爲0嗎》

http://bbs.csdn.net/topics/390091038

好比我有一個對象A,含有一個指向某個對象(例如QUdpSocket)的指針,該對象A經過movetothread移動了一個次線程,而後在次線程中new了一個QUdpSocket對象,並把地址賦值給了對象A的那個指針,這樣QUdpSocket對象也是在次線程中了。
個人問題是,我須要在次線程析構前刪除掉對象A,所以須要給A寫一個析構函數。在函數體裏對指向socket的指針調用deletalater(),這樣在回到次線程的時間循環後就能安全的刪除指針所指對象了。可是我能在調用完deleterlater後直接將
指針賦值爲null嗎,也即:

if(m_udpsocket)
{
      m_udpsocket->deletaLater();
      m_udpsocket = 0;
}

文檔中說deleterLater並非當即被調用,而是把這個刪除時間加入到一個事件循環裏了。因此,我想若是按照上面的代碼所寫,會不會出現這種狀況:當刪除事件加入循環隊列後,指針被賦值爲0,接着刪除事件被處理,這時由於指針爲0,因此堆對象刪除失敗,形成了內存泄露?我本身在下面試了下,沒有遇見這種狀況,但仍是以爲不妥,不該該在後面對指針賦值爲0.可是不這樣作的話,那這個指針豈不就成了一個野指針。在別的狀況,我可能還想屢次重複利用這個指針,那這樣不就用不了了嗎?

 

答:固然能夠,deleteLater並不依賴於這個指針的值,只能使用直接調用函數的方式,

  不能使用connect(p***, SIGNAL(disconnected()), p***, SLOT(deleteLater()));  

                   connect(p***, SIGNAL(disconnected()), this, SLOT(sltClose()));

       void sltClose()

       {                  

          p***=NULL;//槽函數調用沒有固定順序

        }

看http://www.cnblogs.com/liushui-sky/p/5851936.html中

注:我理解調用deletelater (如指針QTcpSocket *p調用 p->deletelater();)以後已經把當前的QTcpSocket 對象的內存地址經過this賦值給消息隊列了,因此把外部的指針p置爲NULL不影響最終對象的delete。

記住:p存放的是指向QTcpSocket對象的內存地址,而p自己只是一個指針地址。

 

參考:http://blog.csdn.net/zzwdkxx/article/details/50748908

相關文章
相關標籤/搜索