内存泄漏问题;删除指针

时间:2011-02-25 10:07:01

标签: c++ pointers delete-operator

如果我有一个指针指向堆上的特定内存地址。我希望这个相同的指针指向另一个内存地址,我应该首先delete指针吗?但是,在这种情况下,我实际上是删除了指针还是只是破坏了指针指向的引用(内存地址)?

所以,换句话说,如果我delete指针,这是否意味着它不再存在?或者,它在那里,但没有指出它在哪里?

6 个答案:

答案 0 :(得分:6)

delete的语法有点误导。当你写

T* ptr = /* ... */
delete ptr;

删除变量ptr。而是删除ptr指向的对象。 ptr的值保持不变,它仍然指向以前的位置,因此如果没有先重新分配它,请务必不要取消引用它。

在重新分配之前,不要求delete指针。但是,如果要以一种导致丢失对指向对象的最后一个引用的方式重新分配指针,则应该确保(例如,如果此指针是程序中指向其指针的唯一指针),然后你应该delete它以确保你不会泄漏记忆。

许多C ++程序员用来简化何时释放内存的逻辑的一种技术是使用smart pointers,这些对象会重载模拟指针所需的运算符,并且具有自动执行的自定义代码以帮助跟踪资源。例如,新的C ++ 0x标准将为此提供shared_ptrunique_ptr类型。 shared_ptr的作用类似于常规指针,不同之处在于它跟踪资源有多少shared_ptr个。当资源的最后shared_ptr更改它指向的位置(通过重新分配或被销毁)时,它将释放资源。例如:

{
    shared_ptr<int> myPtr(new int);
    *myPtr = 137;
    {
       shared_ptr<int> myOtherPtr = myPtr;
       *myPtr = 42;
    }
}

请注意,此代码中没有任何地方可以调用delete来匹配对new的调用!这是因为shared_ptr足够智能,可以在最后一个指针停止指向资源时注意到。

使用智能指针时需要注意一些特性,但是值得花时间投资来学习。一旦了解了它们的工作原理,就可以编写更清晰的代码。

答案 1 :(得分:1)

当您delete指针时释放分配给指向对象的内存。因此,如果您只希望指针指向新的内存位置,则应该 delete指针。但是如果你想销毁当前它所指向的对象,然后指向另一个对象,那么你应该delete指针。

答案 2 :(得分:1)

xtofl,虽然有趣,但有点正确。

如果你'新'是一个内存地址,那么你应该删除它,否则不管它。也许你正在考虑太多,但你想到这样。是的,记忆总是在那里,但是如果你在它周围放一个围栏,你需要把篱笆放下来,或者没有其他人可以使用它。

答案 3 :(得分:1)

当您调用delete时,您将指针指向的内存标记为空闲 - 堆获取它的所有权并可以重复使用它,全部是the pointer itself is usually unchanged

如何处理指针取决于你想要什么。如果您不再需要该内存块 - 请使用delete释放该块。如果您以后需要它 - 将地址存储在稍后可以检索它的地方。

答案 4 :(得分:1)

简而言之,你没有“删除一个指针”,你删除指针指向的任何东西。

这是一个经典问题:如果你删除它,而其他人指向它,它们将读取垃圾(并且很可能会使你的应用程序崩溃)。另一方面,如果你没有,这是最后一个指针,你的应用程序将泄漏内存。

另外,指针可以指向最初未被“新”分配的东西,例如,静态变量,堆栈上的对象或另一个对象的中间。在所有这些情况下,你不允许删除指针指向的任何内容。

通常,在设计应用程序时,您(是的,您)必须决定应用程序的哪个部分拥有特定对象。只有它,它应该在完成后删除对象。

答案 5 :(得分:1)

直接回答您的问题,之前已经提出过这个问题。 delete将删除指针指向的内容,但Bjarne Stroustrup建议不再依赖指针本身的值,特别是如果它是l值。但是,这不会影响重新分配它的能力,因此这将是有效的:

for( p = first; p != last; ++p )
{
   delete p;
}

如果你正在迭代指针数组,所有指针都已经分配了new

C ++中的内存管理最好使用一种称为RAII的技术,“资源获取是初始化”。

这实际上意味着,在您分配资源时,您会立即处理它的生命周期,即您通过将其置于某个对象中来“管理”它,当它不再需要时将为您删除它。

shared_ptr是一种常用的技术,资源将在许多地方使用,你不确定哪一个是最后一个“释放”它,即不再需要它。

shared_ptr通常仅在其他地方用于语义,即您可以轻松地复制和分配它们。

还有其他内存管理智能指针,特别是std :: auto_ptr,它将被unique_ptr取代,并且还有scoped_ptr。 weak_ptr是一种能够获得shared_ptr的方法,如果一个存在于某个地方,但不能自己持有一个引用。如果所有当前的共享指针都已消失,则调用“lock()”为内存提供shared_ptr或为NULL提供NULL。

对于数组,您通常不会使用智能指针,只需使用向量。

对于字符串,通常使用字符串类,而不是将其视为char的向量。