C++:释放动态数组(结构成员)和指向该结构的指针的方法

C++: ways to free a dynamic array (member of a struct) and a pointer to this struct

全部。 假设我们有一个指向结构的指针,它有一个成员是动态数组(在其他成员中)。

我可以释放所有对象,但希望您对针对此特定情况的最佳实践提出意见。请参阅下面的代码,该代码编译并且 运行s 没有分段错误:

#include <iostream>

struct TestStruct
    {
    int a;  // And other members here
    int *b = new int[10];

    ~TestStruct()
        {
        }
    };

int main(void)
    {
    struct TestStruct *a_struct = new TestStruct();

    // Do something with the struct

    delete[] a_struct->b;
    delete a_struct;

    return 0;
    }

这样我假设内存已正确返回。但是,如果我将这些删除中的任何一个移动到析构函数中,就会出现段错误。也就是说,如果我将数组删除移动到析构函数(delete[] a_struct->b;),它不再可访问,因为我删除了之前指向结构的指针(delete a_struct;),反之亦然,内存泄漏发生了。

读完这个帖子C++ free all memory used by struct,有点没有定论,因为大多数建议都被认为是理所当然的工作,但其中很多都存在段错误。

我已经简化了问题,因为我将使用的数组是 3D。如果无法在析构函数中释放 100% 的内存,那么我准备使用一种方法来 运行 循环来释放数组内存和指向结构的指针。所以我想知道你对这个具体情况的看法。

正确的 RAII 方法是:

struct TestStruct
{
    int a;  // And other members here
    int *b = new int[10];

    ~TestStruct()
    {
            delete[] b;
    }
};

int main(void)
{
    struct TestStruct *a_struct = new TestStruct();

    delete a_struct;

    return 0;
}

正确的设计不允许通过同一个指针字段进行多次删除。如果存在这种风险,可以将nullptr赋值给指针。删除空指针是noop.

RAII(Resource acquisition is initialization)本质上归结为:谁分配内存谁释放。

在析构函数中,只删除动态分配的成员,而不是对象本身(这是在析构过程中完成的)。

所以下面的代码应该没问题:

struct TestStruct
{
  int a;  // And other members here
  int *b = new int[10];

  ~TestStruct() {
     delete[] b;
  }
};

int main(void)
{
  struct TestStruct *a_struct = new TestStruct();

  // Do something with the struct

  delete a_struct;

  return 0;

}

由于您使用的是 C++ 和动态数组,因此 std::vector, std::array, or, e.g., std::unique_ptr 是比直接使用 new 更好的处理方法。