为已删除的对象分配值

时间:2013-04-29 02:48:11

标签: c++ pointers

我有一个小作业问题 提供以下代码:

int * p;
p = new int;
*p = 5;

问题是:为什么这样做无用

p = 0;
delete p;

但有用

delete p;
p = 0;

在我看来,两者都没用。如果删除了某个对象,则不能分配新值 我在这两种情况下都得到Segmentation fault

5 个答案:

答案 0 :(得分:5)

为什么它对以下内容有用:

delete p;
p = 0;

引自stroustrup的回答:Why doesn't delete zero out its operand?

  

考虑

delete p;
// ...
delete p;
     

如果...部分没有触及p则第二个“删除p;”是一个严重的错误,C ++实现无法有效地保护自己(没有异常的预防措施)。 由于根据定义删除零指针是无害的,因此一个简单的解决方案是“删除p;”做一个“p = 0;”在完成其他任何需要之后。但是,C ++并不保证。   一个原因是删除的操作数不必是左值。考虑:

delete p+1;
delete f(x);
     

这里,delete的实现没有指向零的指针。这些示例可能很少见,但它们确实意味着无法保证any pointer to a deleted object is 0.'' A simpler way of bypassing that规则''有两个指向对象的指针:

T* p = new T;
T* q = p;
delete p;
delete q;   // ouch!
     

C ++明确允许delete的实现将左值操作数归零,我曾希望实现会这样做,但这个想法似乎并没有受到实现者的欢迎。   如果您认为将指针归零很重要,请考虑使用destroy函数:

template<class T> inline void destroy(T*& p) { delete p; p = 0; }
  

考虑这个 - 另一个原因是依靠标准库容器,句柄等来最小化对new和delete的显式使用。

     

请注意,将指针作为引用传递(以允许指针为零)可以防止对rvalue调用destroy():

int* f();
int* p;
// ...
destroy(f());   // error: trying to pass an rvalue by non-const reference
destroy(p+1);   // error: trying to pass an rvalue by non-const reference

答案 1 :(得分:2)

回想一下,允许删除0。因此,当你这样做时

p = 0;
delete p; // Deleting zero is ignored

你丢弃p的旧值(从而造成内存泄漏),然后调用被忽略的delete 0

但是,当你这样做时

delete p;
p = 0;

首先使用旧值(取消分配int),然后将其归零。这是有道理的,因为p的旧值在执行delete后变得无用且危险。

答案 2 :(得分:0)

这将指针设置为null,然后调用delete:

p = 0;
delete p;

就像说

delete 0;

我认为你在想的是它设置了p指向零的int,但是这样就可以这样做:

*p = 0;

答案 3 :(得分:0)

在第一种情况下,您将POINTER p的值指定为“0”,而不是p指向的int的值。这就是为什么它既无用(实际上会导致内存泄漏),并且当你尝试从内存地址'0'删除时会导致seg错误。编辑 - 实际上我刚刚得知段错误不是由'删除0'引起的,根据标准被忽略,所以其他东西导致了。

在第二种情况下,你释放p指向的内存/对象(应该没问题),然后将指针赋值为'0',这也应该是Ok,所以不确定为什么你是那里有错误吗?在有用性方面,过去被认为是将free'd指针设置为null或'0'值的好习惯,因此您可以在取消引用之前对其进行测试。

答案 4 :(得分:0)

p = NULL;

p = 0;

在上面的例子中,您要为指针赋值,而不是指向它所指向的对象。

是同一个人。 delete函数用于释放动态分配给对象的内存。

  1. 当你说

    delete p;
    p = 0;
    

    这就像说释放分配给指针p的内存 那你要说指针指向NULL。哪个是对的。

  2. 在您执行此操作的其他情况下

    p = 0;
    delete p;
    

    您说首先将指针指定为NULL。现在指针p 没有指向任何有效的动态分配内存。好迟啊 当你说删除p时,编译器找不到任何可以释放的内存 因而引发了分段错误。