使用delete关键字删除具有动态分配块的对象是否安全

时间:2012-12-30 00:45:07

标签: c++ memory-management

对于某些人来说,这个问题听起来可能太简单了,但我试图了解如果使用删除关键字

删除具有动态分配块的对象会发生什么

调用delete将执行两项操作,首先调用析构函数然后释放内存。 如果delete正在释放对象内存,那么它还会释放动态分配的内存,或者我是否必须在析构函数中编写一个代码块来实际释放内存块。

此外,如果对象在堆中分配了内存,那么除了成员变量之外的其他内容将占用分配给该对象的内存。

提前致谢

5 个答案:

答案 0 :(得分:4)

如果你有这样的事情:

class Foo
{
public:
   int* block;

   Foo()
   {
       block = new int[10];
   }

private:
   Foo(const Foo&);
   Foo& operator =(const Foo&);
};

然后这样做:

Foo* foo = new Foo;
delete foo;

然后是的,你是在泄漏记忆。永远不会释放Foo对象中的动态块。您可以使用释放它的析构函数来解决这个问题。 (源代码,您还需要在类声明中声明析构函数):

Foo::~Foo()
{
    delete [] block;
}

我建议你做两件事

  1. 计算删除和新的。如果它们不相同,那通常是一个问题。
  2. 使用C ++阅读此informative document关于动态指针和内存使用情况。
  3. 关注#2,btw,可能会给你一个看起来类似于此的对象:

    class Foo
    {
    public:
       std::array<int,10> block;
    
       Foo() // note: default-construction of `block`
       {
       }
    
       // note: default *destructor* will clean up member variables
       //  by firing their destructors for you. in this case the destructor
       //  for our 'block' member is a std::array that knows how to self-clean.
    
       // note: we no longer have to hide or implement copy construction and
       //  assignment operator functionality. The default implementation of 
       //  these properly member-copy and member-assign respectively.
    };
    

    这样的用法(许多可能之一):

    std::unique_ptr<Foo> foo(new Foo);
    

    请注意上一个例子来源中的注释。通过使用练习自我管理成员的课程,你的记忆管理肩膀上有一个巨大的重量。在提升重量的同时,也有可能引入与其相关的错误,如内存泄漏,浅拷贝危险等。

答案 1 :(得分:1)

调用delete时释放的内存就是对象本身占用的内存。该对象占用了许多连续的字节,并在delete上释放。 sizeof(MyType)将显示有多少字节。并且没有其他由delete发布。其他所有东西都是由析构函数(或由各个成员对象的析构函数)释放的

答案 2 :(得分:1)

使用动态分配的块,您需要调用delete []。

例如:

class C
{
    //some members
public:
    C() {...}
    ~C() {...} 
    // some methods
};

int main()
{
C * arr = new C[10]; // Dynamically allocated memory

// some code using arr . . .

delete[] arr; // Calling ~C() for each C element in arr and then releasing the dynamically alloacted memory on the heap pointed by arr.
}

但是,如果另外你有一个动态分配的memeber指针,你需要在对象的析构函数中删除它:

C::C()
: memberArray(new int[10]) {  }

C::~C()
{
   delete[] memberArray;
   memberArray = NULL;
}

答案 3 :(得分:0)

析构函数的用法是为它包含的每个指针属性调用delete语句。 例如,如果我有一个“car”类,它有一个属性“轮胎”,它将是一个指针,你需要在汽车的析构函数中删除这个属性。

答案 4 :(得分:0)

不,分配的内存不会被释放。

当删除分配动态内存并将其分配给指针的对象时,将仅释放指针,而不释放指向的数据。当一个对象分配了内存时,必须在其析构函数中手动调用该数据的删除,或者确保它被其他一个指向该数据的对象删除。

自动删除它是不可能的,因为该对象可能已经将已分配的数据传递给另一个在删除分配对象后仍需要它的对象。