Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.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++ delete命令会清除分配给new的内存吗?_C++ - Fatal编程技术网

C++ delete命令会清除分配给new的内存吗?

C++ delete命令会清除分配给new的内存吗?,c++,C++,我试图理解delete是如何清除分配给对象的内存的。 有人能解释清楚吗 我在做这样的事情: class MyClass{ public : MyClass() {std::cout <<" constructed\n";} ~MyClass() {std::cout <<" destroyed\n";} }; int main () { MyClass * pt=NULL; pt = new MyClass(); delete

我试图理解delete是如何清除分配给对象的内存的。 有人能解释清楚吗

我在做这样的事情:

class MyClass{
public :
    MyClass() {std::cout <<" constructed\n";}
    ~MyClass() {std::cout <<" destroyed\n";} 
};
int main () 
{
    MyClass * pt=NULL;
    pt = new MyClass();
    delete pt;
    if ( pt == NULL ) 
        std::cout<<"deallocated\n";
}
class-MyClass{
公众:

MyClass(){std::cout
delete pt
将调用析构函数
~MyClass()
,然后将对象
*pt
占用的所有内存释放回操作系统

它没有做的是更改指针的值,因为这是不必要的


<> >某些程序员在<代码>删除>代码之后设置<代码> Pt= NulLPTR < /代码>,因为C++标准保证<>代码>删除NulLPTR < /C> >是NO-OP。因此它可以帮助程序稳定性。

<代码>删除P<代码>确实释放了由“代码> P<代码/代码>的值指向的对象所占用的存储,除此之外。

它没有修改<代码> p<代码>的值。这是没有意义的。考虑一下:

int * funky_ptr();

delete funky_ptr();
这里,
delete
的操作数是一个prvalue;修改它有什么意义呢?

这取决于它

在调试版本中,一些编译器通常会清除内存(或者将所有内容设置为
0
,或者设置一些稍后可用于标识清除的位模式),以帮助调试

这样,访问一个已删除的对象很可能会在早期产生访问冲突,而不是悄无声息地失败

在发布版本中,除了调用(伪)析构函数之外,没有其他事情发生

请注意,在
delete
free
之后设置指向
NULL
的指针是一种代码气味,因为它会掩盖一些错误

我想了解delete是如何清除分配给对象的内存的。有人能说清楚吗

delete
delete执行以下操作:

  • 查看接收到的地址,并将其解释为指针(指向指针类型指定的数据)

  • 为接收地址处的所有数据实例和对象调用析构函数

  • 告诉内部内存分配子系统,接收到的指针中的地址现在是空闲的。这将释放内存到操作系统(以便其他应用程序可以使用它),或者(更有可能)在内部缓存内存并将其用于后续分配(下一次分配使用
    new
    new[]
    大小相同或更小的用户可能会收到此指针)

这些是在C++中释放堆数据的最小步骤。 您会注意到,该列表中没有“设置指向null/zero/specific value的指针”。这是因为在某些情况下,在delete语句之后(例如,在析构函数体中),指针的值不感兴趣,而将其设置为零只会浪费处理器周期

作为一个经验法则,C++代码是这样编写的,所以你不为你不使用的东西付费。如果你有这样的功能,自己编写它是微不足道的(这个例子对于数组来说是不行的):

模板
void safe_delete(T*&ptr)//使用而不是删除
{
删除ptr;
ptr=nullptr;
}

到底什么是不清楚的?
delete pt
销毁
MyClass
对象(调用其析构函数)并释放其占用的内存。它不会修改指针
pt
,指针保持“悬空”,并带有无效值。如果由于作用域的原因,pt不会被销毁,则需要显式地将其赋值为NULL。然后,“new”实现这一点的方法是使用智能指针、共享指针等,而不必处理它。“分配的内存”通常不会被清除,至少不会被空闲调用清除。它可能会或可能不会变得不可访问(但通常,出于测试目的,您可以访问它并查看其中的内容)。没有魔法。唯一发生的事情是,下一次分配可能会使用释放的内存。
delete pt,pt=nullptr;
,这是我将多条指令放在一行中的唯一实例。但是,您必须注意一个折衷,即如果将指针设置为null,则无法检测到多个释放,因此此类错误将是h很难找到。当然,我们在实际代码中没有做很多原始的
新的
删除
,是吗?@coyotte508(/cc bathsheba)释放后设置为null不是一个好主意。如果你在
删除后访问指针,这很可能是一个逻辑错误,你不想隐藏它。@LuchianGrigore:我同意大多数情况,但是设置为
null
可能会节省时间,比如说,如果你的代码库发现自己在火星着陆器或wHATNOT。我明确地反对使用<代码>删除<代码>,但是依赖于共享的和唯一的指针类。主要是这样我不会在半夜惊慌地醒来。@克里斯一个“错误”可能被隐藏,但是另一个被删除的指针被访问(可能在空闲之后)。将被一个响亮的SIGSEV和一个漂亮的调用堆栈检测到,在我看来,这种错误更严重。
template<typename T>
void safe_delete(T*& ptr) // use instead of delete
{
    delete ptr;
    ptr = nullptr;
}