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

Is it safe to delete an object having a dynamically allocated block using delete keyword

本文关键字:对象 是否 安全 动态分配 关键字 delete 删除 使用      更新时间:2023-10-16

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

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

调用delete会做两件事,首先调用析构函数,然后释放内存。如果delete正在释放对象内存,那么它是否也会释放动态分配的内存,或者我是否必须在析构函数中编写代码块来实际安全地释放内存块。

如果对象在堆中分配了内存,那么除了成员变量之外,还有什么其他东西会占用分配给对象的内存呢?

Thanks in advance

如果你有这样的东西:

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++动态指针和内存使用的信息文档。
顺便说一句,在#2之后,可能会给你一个类似于下面的对象:
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);

请参考最后一个例子来源中的注释。通过使用实践自我管理成员的类,您的内存管理肩上减轻了巨大的负担。在提升这个权重的过程中,引入与之相关的bug的可能性也随之增加,比如内存泄漏、浅拷贝风险等

调用delete时释放的内存就是对象本身占用的内存。对象占用了一些连续的字节,这些字节在delete上被释放。sizeof(MyType)会告诉你有多少字节。delete不释放其他。其他所有内容都由析构函数(或单个成员对象的析构函数)释放

使用动态分配的块时,需要调用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.
}

但是,如果另外还有动态分配的成员指针,则需要在对象的析构函数中删除它:

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

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

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

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

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