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

相关文章
相关标签/搜索