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

C++ C++;:释放动态数组(结构的成员)和指向此结构的指针的方法,c++,arrays,memory,struct,raii,C++,Arrays,Memory,Struct,Raii,全部。 假设我们有一个指向一个结构的指针,它有一个成员是动态数组(在其他成员中) 我可以释放所有对象,但需要您对这种特定情况下的最佳实践的意见。请参阅下面的代码,该代码编译并运行时不会出现分段错误: #include <iostream> struct TestStruct { int a; // And other members here int *b = new int[10]; ~TestStruct() {

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

我可以释放所有对象,但需要您对这种特定情况下的最佳实践的意见。请参阅下面的代码,该代码编译并运行时不会出现分段错误:

#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;
    }
#包括
结构测试结构
{
int a;//和这里的其他成员
int*b=新的int[10];
~TestStruct()
{
}
};
内部主(空)
{
struct TestStruct*a_struct=new TestStruct();
//对struct执行一些操作
删除[]a_结构->b;
删除一个结构;
返回0;
}
这样的话,我假设内存被正确返回。但是,如果我将这些删除中的任何一个移动到析构函数,就会出现segfault。也就是说,如果我将数组删除移动到析构函数(
delete[]a_-struct->b;
),它将不再可访问,因为我在之前删除了指向该结构的指针(
delete a_-struct;
),反之亦然,并且会发生内存泄漏

在阅读了这篇文章之后,它有点没有定论,因为大多数建议都被认为是理所当然的,但它们中的许多都有缺陷


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

正确的解决方法是:

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(资源获取即初始化)本质上归结为:谁分配了内存,谁就释放了内存。

正确的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;

}

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

因此,以下代码应该可以:

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++和动态数组,或者,例如,都是比使用<代码>新< /COD>直接处理的更好的方法。

< P>因为你使用C++和动态数组,或者,例如都是比直接使用
new
更好的处理方法。

使用
std::array
std::vector
。使用
std::array
std::vector
。LOL,在同一秒内。。。另外,从技术上讲,您可以
删除此
,但如果从析构函数执行此操作,则会导致析构函数的递归调用。@Stephan,谢谢,但这是我在上面对Swift的评论中提到的问题。在问这个问题之前我已经试过了。删除一个_结构后,析构函数中的delete[]b会导致一个segfault(一个_结构不再可访问)。@JayY:
delete a _结构
实际上会触发析构函数,析构函数中的,
这个
总是可访问的(否则任何析构函数代码都没有多大意义)。你确定你删除了
main
中的
delete[]a_struct->b
?@StephanLechner是的,我以前试过这个,但是如果我已经删除了main()中的内容,它会在析构函数中的任何delete命令上出错。我已经准备好了编译器,可以接受这里的任何建议。@JayY我不明白为什么发布的代码会出错。你用那个密码试过了吗?哈哈,就在同一秒钟。。。另外,从技术上讲,您可以
删除此
,但如果从析构函数执行此操作,则会导致析构函数的递归调用。@Stephan,谢谢,但这是我在上面对Swift的评论中提到的问题。在问这个问题之前我已经试过了。删除一个_结构后,析构函数中的delete[]b会导致一个segfault(一个_结构不再可访问)。@JayY:
delete a _结构
实际上会触发析构函数,析构函数中的,
这个
总是可访问的(否则任何析构函数代码都没有多大意义)。你确定你删除了
main
中的
delete[]a_struct->b
?@StephanLechner是的,我以前试过这个,但是如果我已经删除了main()中的内容,它会在析构函数中的任何delete命令上出错。我已经准备好了编译器,可以接受这里的任何建议。@JayY我不明白为什么发布的代码会出错。你用那个密码试过了吗?谢谢你的回复。但是,正如我前面提到的,当我们在析构函数中尝试删除[]b时,这样做会导致segfault,因为delete a_struct已经删除了对它的引用,因此它不再可访问。作为此答案的一部分发布的代码是正确的AFAICT,并且在我的机器上运行它(MacOS/X,clang++)不会产生运行时错误。在C++中,在TestStutt内存被回收之前执行TestStult析构函数,因为否则会使析构函数不可能释放任何资源。我认为,如果您遇到segfault,肯定还有其他原因。@JayY唯一可能出现segfault的原因是堆之前不知何故已损坏。你们并没有发布失败的代码,所以问题不在这里reproducable@Swift您建议的代码,我在这里提问之前尝试过的代码,导致了SEG错误。我尝试了几种不同的编译器(g++,MSVC)。在我看来,正在发生的事情是:1)程序释放了pointe的内存