Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为删除的对象赋值_C++_Pointers - Fatal编程技术网

C++ 为删除的对象赋值

C++ 为删除的对象赋值,c++,pointers,C++,Pointers,我有一个小作业问题。 给出了以下代码: int * p; p = new int; *p = 5; 问题是:为什么这样做毫无用处 p = 0; delete p; 但这样做是有用的 delete p; p = 0; ? 在我看来,两者都是无用的。如果删除对象,则无法分配新值。 在这两种情况下,我都会得到一个分段错误这会将指针设置为null,然后调用delete: p = 0; delete p; 就像说 delete 0; 我想你所想的是,它将p指向的int设置为零,但这是这样做的:

我有一个小作业问题。
给出了以下代码:

int * p;
p = new int;
*p = 5;
问题是:为什么这样做毫无用处

p = 0;
delete p;
但这样做是有用的

delete p;
p = 0;
?

在我看来,两者都是无用的。如果删除对象,则无法分配新值。

在这两种情况下,我都会得到一个
分段错误

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

p = 0;
delete p;
就像说

delete 0;
我想你所想的是,它将p指向的int设置为零,但这是这样做的:

*p = 0;

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

p = 0;
delete p; // Deleting zero is ignored
p = 0;
delete p;
您丢弃了
p
的旧值(从而造成内存泄漏),然后调用
delete 0
,该值将被忽略

然而,当你这样做的时候

delete p;
p = 0;

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

在第一种情况下,您将指针p的值指定为“0”,而不是p指向的int的值。这就是为什么当您尝试从内存地址“0”中删除时,它既没有用处(实际上会导致内存泄漏),又会导致seg故障。编辑-事实上,我刚刚了解到SEGFULT不是由“delete 0”引起的,根据标准,删除0被忽略,因此是其他原因造成的


在第二种情况下,您正在释放p指向的内存/对象(这应该可以),然后将指针指定为具有值“0”,这也应该是正常的,因此不确定为什么会在那里发生seg故障?就有用性而言,将自由指针设置为null或“0”值是一种良好的做法,这样您就可以在取消引用它们之前对其进行测试。

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

delete p;
p = 0;
引用stroustrup的回答:

考虑

delete p;
// ...
delete p;
如果。。。部分不触碰P,那么第二个“删除p”是一个严重错误,C++实现不能有效地保护它自己(没有特殊的预防措施)。因为定义了删除一个零指针是无害的,一个简单的解决办法是“删除p”;在它做了其他所需要的之后,做一个“p=0”,但是,C++不能保证。 一个原因是delete的操作数不必是左值。考虑:

delete p+1;
delete f(x);
在这里,delete的实现没有一个指针,可以将其赋值为零。这些示例可能很少,但它们确实意味着不可能保证指向已删除对象的
任何指针为0。“绕过该
规则的一种更简单的方法是使用两个指向对象的指针:

T* p = new T;
T* q = p;
delete p;
delete q;   // ouch!
C++显式地允许delete实现将左值操作数归零,我曾希望实现能做到这一点,但这种想法似乎并不受实现者的欢迎。 如果考虑将指针减为零,请考虑使用销毁函数:

在上述情况下,您将为指针赋值,而不是为指针指向的对象赋值

都是一样的。删除函数用于释放动态分配给对象的内存

  • 当你说

    delete p;
    p = 0;
    
    这就像释放分配给指针p和p的内存一样 然后您说的是将指针赋值为NULL。这是正确的

  • 在另一种情况下,当你这样做

    p = 0;
    delete p; // Deleting zero is ignored
    
    p = 0;
    delete p;
    
    您的意思是首先将指针分配给NULL。现在指针是p 未指向任何有效的动态分配内存。那么以后呢 当您说delete p时,编译器找不到任何要释放的内存 因此抛出了一个分段错误


  • 如果
    删除p;p=0给了你一个Sebug,你做了其他错误。我试图返回<>代码> p>代码>。这样的教学就是为什么C++有一个坏名声,它是一个内存泄漏/损坏的难用语言。现在使用C++11,您不应该在代码中写入delete*。在C++14中添加了make_unique,您永远不应该在代码中编写新代码*。(*=除非你是编写低级别组件的专家),而C++编译器在试图删除它时会忽略零值指针,即IE将编译而不出错。但是,这在运行时肯定会导致seg故障。@Ozraptor不符合标准:允许
    delete 0
    free(NULL)
    。这是一个运行示例:.@Ozraptor:这是标准第5.3.5节段落明确允许的2@dasblinkenlight沃恩·卡托:那我得试试这个。这种情况一直都是这样,还是C++11的变化?我确信“delete(0)”会导致seg故障,正如上面的原始海报所示?@Ozraptor据我所知,这一直是这样的(我怀疑它是模仿C中的
    free
    行为建模的)。至于OP的segfault,我认为它来自一些无关的东西,比如不从
    main
    返回
    0
    ,或者类似的简单东西。
    delete p;
    p = 0;
    
    p = 0;
    delete p;