2011-02-25 122 views
2

如果我有一个指针指向堆中的特定内存地址。我想这相同指针指向另一个内存地址,我应该先指定delete指针吗?但是,在这种情况下,我实际上删除了指针还是仅仅打破了指针指向的引用(内存地址)?内存泄漏问题;删除指针

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

+3

除了给出的答案,请注意,C++也有新的[]和delete []操作符,它们不仅仅分配/删除一个对象,而是整个数组。这是该语言令人难以置信的愚蠢特征,因为它在忘记[]时很容易造成内存泄漏。到目前为止,最好的解决方案是根本不会摆弄新的/删除,而是使用智能指针类:http://en.wikipedia.org/wiki/Smart_pointer – Lundin 2011-02-25 10:22:24

回答

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

当你delete一个指针,你释放分配给内存指出对象。所以,如果你只是想让你的指针指向一个新的内存位置,你应该是而不是delete指针。但是如果你想破坏它目前指向的对象,然后指向一个不同的对象,那么你应该delete指针。

1

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

如果您'新建'了一个内存地址,那么您应该删除它,否则请不要管它。也许你在想太多,但你会这样想。是的,记忆永远在那里,但是如果你围着它,你需要把围栏放下,否则没有其他人可以。

+0

我认为这应该是最简单的规则:一个新的==一个删除。不要打扰更多。然而尝试避免新闻;) – 2011-02-25 10:20:00

1

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

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

1

总之,你不“删除指针”,你删除指针指向的任何东西。

这是一个古典问题:如果你删除它,并且别人指向它,它们将读取垃圾(并且很可能会导致应用程序崩溃)。另一方面,如果你不知道这是最后一个指针,你的应用程序将会泄漏内存。另外,指针可能指向最初不是由“新”分配的东西,例如,一个静态变量,堆栈中的对象或另一个对象的中间。在所有这些情况下,您不允许删除指针指向的任何内容。

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

1

要直接回答你的问题,这已经被问过。 delete会删除你的指针指向的内容,但是Bjarne Stroustrup提出了一个建议,指针本身的值不能再被依赖,特别是如果它是一个l值。如果你迭代指针,所有这些都被分配与new阵列

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

:但是这并不影响到其重新分配所以这将是有效的能力。

C++中的内存管理最好用称为RAII的技术“资源获取是初始化”来完成。

这实际上意味着当你分配资源的时候,你立即关心它的生命周期,即你通过将它放入一个对象中来“管理”它,当它不再需要的时候将会删除它。

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

shared_ptr通常在其他地方仅用于其语义,也就是说您可以很容易地复制和分配它们。

还有其他内存管理智能指针,特别是std :: auto_ptr,它将被unique_ptr取代,还有scoped_ptr。 weak_ptr是一种能够获得shared_ptr的方法,如果某个地方存在shared_ptr,而不是自己持有引用。你可以调用“lock()”给你一个shared_ptr给内存,或者如果所有当前的共享指针都不存在,那么它就是NULL。

对于数组,您通常不会使用智能指针,而只是使用矢量。

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