NULL指针与解除分配相同吗?

时间:2009-11-24 11:18:19

标签: c++

我正在研究一段代码而且我受到了一个疑问:如果我为该指针分配NULL,分配给指针的内存会发生什么变化?

例如:

A = new MyClass();

{...do something in the meantime...}

A = NULL;

仍然分配了空间,但没有提及它。这个空间以后会被释放,它会被重用,它会保留在堆栈中,还是什么?

11 个答案:

答案 0 :(得分:32)

这是一个经典的泄漏。 正如你所说,内存仍然是分配的,但没有任何东西引用它,因此它永远不会被回收 - 直到进程退出。

应该使用delete释放内存 - 但是使用智能指针(例如std :: auto_ptr或boost :: shared_ptr(或tr1 :: shared_ptr)来包装指针是一种更安全的指针处理方式。) p>

以下是使用std :: auto_ptr重写示例的方法:

std::auto_ptr a( new MyClass() );

/*...do something in the meantime...*/

a.reset();

(而不是调用reset(),你可以让auto_ptr实例超出范围)

答案 1 :(得分:25)

在大多数情况下,这会导致进程中的内存泄漏。您可以使用多种方法在C ++中管理内存。

  1. 完成后,使用delete手动释放内存。这很难做到,特别是在异常处理的情况下。

  2. 使用智能指针为您管理内存(auto_ptr,shared_ptr,unique_ptr等)

  3. C ++没有垃圾收集器,但是如果你想沿着那条路走下去,没有什么能阻止你使用它(例如Boehm GC)。

答案 2 :(得分:10)

这是内存泄漏。您必须删除手动分配的内存。

答案 3 :(得分:5)

您需要delete A;

对于常规对象,将指针设置为NULL只会使指针无效,对象仍然在内存中,如果您注意到可能有多个指向同一对象的指针,则更为明确影响其他人。

答案 4 :(得分:5)

A = new MyClass();

{...do something in the meantime...}

A = NULL;

我跟踪它的方式是有两个独立的对象。堆上的某处MyClass实例由new分配。在堆栈上,有一个名为A的指针。

A只是一个指针,没有任何神奇的东西,它没有与堆分配的MyClass对象的某些特殊连接。它恰好恰好指向现在,但这可能会改变。

在最后一行,这正是发生的事情。您将指针更改为指向其他内容。这不会影响其他对象。它不会影响它用来指向的对象,也不会影响它设置为指向的对象(如果有的话)。同样,A只是一个愚蠢的原始指针,就像任何其他指针一样。它可能是NULL,或者它可能指向堆栈上的对象,或者它可能指向堆上的对象,或者它可能未初始化并指向随机垃圾。但就是这样。它指出,它不会以任何方式取得它所指向的对象的所有权或修改它。

答案 5 :(得分:3)

在大多数现代操作系统上,应用程序的内存将在退出应用程序时回收。与此同时,你有内存泄漏。

答案 6 :(得分:3)

根据Phil Nash的评论,对于每一个新的,都有相应的删除,同样,对于每个malloc,都有相应的免费。如果没有相应的删除/免费,则表示您有泄漏。

希望这有帮助, 最好的祝福, 汤姆。

答案 7 :(得分:2)

不,它将永远失去这个过程。你会有内存泄漏。如果你继续这样做,你的程序最终会耗尽内存!为了避免这种情况,当您不再需要它时,delete该对象。

通常人们会在删除指针后将指针设置为NULL,这样程序的其他部分就可以验证对象是否已被删除,从而避免再次访问或删除它。

答案 8 :(得分:2)

C ++没有垃圾收集器,就像其他语言一样(Java,C#,...),所以你必须自己删除已分配的对象。

答案 9 :(得分:1)

存储在堆栈中的变量是每个函数的局部变量,例如: int big [10]; 存储在堆上的变量是使用显式内存分配例程(如malloc(),calloc(),new()等)启动的变量。

存储在堆栈中的变量的生命周期等于当前堆栈帧的生命周期。在英语中,当函数返回时,您不能再认为变量保持您期望它们保持的状态。这就是为什么返回一个在函数中声明为local的变量的经典错误。

答案 10 :(得分:0)

通过为指针分配NULL,您将无法释放已分配的内存。您应该调用deallocation函数来释放已分配的内存。根据C ++标准5.3.4 / 8:“如果分配的类型是非数组类型,则分配函数的名称为operator new,并且释放函数的名称为operator delete”。我可以建议以下函数安全地删除指针(为它们分配NULL):

template<typename T>
inline void SafeDelete( T*& p )
{
    // Check whether type is complete.
    // Deleting incomplete type will lead to undefined behavior
    // according to C++ Standard 5.3.5/5.
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);

    delete p;
    p = NULL;
}