C++ delete命令会清除分配给new的内存吗?
我试图理解delete是如何清除分配给对象的内存的。 有人能解释清楚吗 我在做这样的事情: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
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::coutdelete 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;
}