C++ 尝试处理嵌套对象/结构时出现内存泄漏或内存错误&;动态数组。可能的Xcode/malloc问题

C++ 尝试处理嵌套对象/结构时出现内存泄漏或内存错误&;动态数组。可能的Xcode/malloc问题,c++,dynamic,malloc,destructor,delete-operator,C++,Dynamic,Malloc,Destructor,Delete Operator,当我用Xcode编译并运行它时,我得到了错误,至少连续100次,malloc:**object 0x100180的错误:double free,调试器指向行C。奇怪的是,在我从中提取的代码中,出现了完全相同的错误,但调试器指向了与行B相当的代码。我试过了,但无法复制 如果我删除行A,代码会正常工作,但会出现严重的内存泄漏,导致程序在大约1分钟内崩溃。删除行C可以解决问题,但不是有效的解决方案,因为类没有正确的析构函数 #include <iostream> #include <

当我用Xcode编译并运行它时,我得到了错误,至少连续100次,
malloc:**object 0x100180的错误:double free
,调试器指向
行C
。奇怪的是,在我从中提取的代码中,出现了完全相同的错误,但调试器指向了与
行B
相当的代码。我试过了,但无法复制

如果我删除
行A
,代码会正常工作,但会出现严重的内存泄漏,导致程序在大约1分钟内崩溃。删除
行C
可以解决问题,但不是有效的解决方案,因为
没有正确的析构函数

#include <iostream>
#include <vector>

struct a_struct
{
    int* dynamic_array;
    a_struct(int length) {dynamic_array = new int [length];}
    a_struct() : dynamic_array(NULL) {}
    ~a_struct() { if (dynamic_array != NULL) {delete [] dynamic_array;} }  //Line A
};

class a_class
    {
    public:
        a_struct* the_structs;
        a_class() {Init();}
        a_class(a_class const & origin) {Init();}
        void Init(){
            the_structs = new a_struct [10];                              //Line B 
            for(int q=0; q<10; q++)
                the_structs[q] = a_struct(7);}
        ~a_class() { if (the_structs != NULL) {delete [] the_structs;} }  //Line C
    };

int main () 
{
    std::vector <a_class> the_objects;
    for(int q=0; q<10; q++)
        the_objects.push_back(a_class());

    while(1)
        for(int q=0; q <10; q++)
            for(int w=0; w <10; w++)
                the_objects[q].the_structs[w] = a_struct(7);
}
#包括
#包括
结构a_结构
{
int*动态_数组;
a_结构(int-length){dynamic_-array=new int[length];}
a_struct():动态_数组(NULL){}
~a_struct(){if(dynamic_array!=NULL){delete[]dynamic_array;}}}//行a
};
甲级
{
公众:
a_struct*该_structs;
_类(){Init();}
a_类(a_类常量和原点){Init();}
void Init(){
_structs=newa_struct[10];//行B

对于(int q=0;q修复一个_结构和一个_类,使其具有适当的复制构造函数和赋值运算符。如果仍然存在问题,请返回


请确保所有类始终遵循。我最近似乎经常链接到该页面。

修复一个\u结构和一个\u类,使其具有适当的复制构造函数和赋值运算符。如果仍然存在问题,请返回


请确保所有类始终遵循。我最近似乎经常链接到该页面。

问题是
a_结构
没有正确的复制构造函数和
operator=
。因此,两个
a_结构::dynamic_数组
每次都指向同一内存位置,并且都将调用
delete[]析构函数中的动态数组;
。因此,双删除

请始终记住,每当您在
类中有行指针时,您应该进行深度复制(复制指针指向的内容),而不是浅层复制(仅复制地址)

在您的情况下,可以如下更改定义:

struct a_struct
{
  int length_;  //<<--- add this for record
  int* dynamic_array;
  a_struct(int length) : length_(length) {dynamic_array = new int [length_]; }
  a_struct() : dynamic_array(NULL) {}
  a_struct(const a_struct &copy)  // <<--- copy ctor
  {
    do_copy(copy);
  }
  a_struct& operator = (const a_struct &copy)  // <<--- assignment operator
  {
    delete[] dynamic_array; // clear earlier array
    do_copy(copy);
    return *this;
  }
  ~a_struct() { if (dynamic_array != NULL) {delete [] dynamic_array;} }  //Line A

  void do_copy (const a_struct &copy)
  {
    // do necessary null checks for "copy"
    dynamic_array = new int[length_ = copy.length];
    memcpy(dynamic_array, copy.dynamic_array, length_);
  }
};
struct a_struct
{

int length//问题是
a_struct
没有正确的复制构造函数和
运算符=
。因此,两个
a_struct::dynamic_array
指向同一内存位置,它们都将在析构函数中调用
delete[]dynamic_array;
。因此,double delete

请始终记住,每当您在
类中有行指针时,您应该进行深度复制(复制指针指向的内容),而不是浅层复制(仅复制地址)

在您的情况下,可以如下更改定义:

struct a_struct
{
  int length_;  //<<--- add this for record
  int* dynamic_array;
  a_struct(int length) : length_(length) {dynamic_array = new int [length_]; }
  a_struct() : dynamic_array(NULL) {}
  a_struct(const a_struct &copy)  // <<--- copy ctor
  {
    do_copy(copy);
  }
  a_struct& operator = (const a_struct &copy)  // <<--- assignment operator
  {
    delete[] dynamic_array; // clear earlier array
    do_copy(copy);
    return *this;
  }
  ~a_struct() { if (dynamic_array != NULL) {delete [] dynamic_array;} }  //Line A

  void do_copy (const a_struct &copy)
  {
    // do necessary null checks for "copy"
    dynamic_array = new int[length_ = copy.length];
    memcpy(dynamic_array, copy.dynamic_array, length_);
  }
};
struct a_struct
{

int length_;//问题在于
a_struct
中隐式生成的复制构造函数不执行深度复制,但析构函数始终假定为每个实例分配了内存。您需要为其创建一个执行深度复制的复制构造函数。但更好的做法是只使用
std::vector
,而不是使用new和d这样你就不必担心记住所有的构造函数都是正确的了


此外,
a_类的复制构造函数实际上并不复制对象。这几乎肯定会在不支持预期的复制语义的情况下给您带来问题。

问题在于,
a_结构
中隐式生成的复制构造函数不执行深度复制,而执行析构函数tor始终假定为每个实例分配了内存。您需要为其创建一个复制构造函数,以执行深度复制。但更好的方法是只使用
std::vector
,而不是使用new和delete。这样您就不必担心记着保持所有构造函数的正确性


此外,
a_类的复制构造函数实际上并不复制对象。这几乎肯定会在不支持预期的复制语义的情况下给您带来问题。

问题是您正在尝试自己进行内存管理

使用内置容器:

struct a_struct
{
    std::vector<int>    dynamic_array;
    a_struct(int length) : dynamic_array(length){}
    a_struct()           : dynamic_array() {}
};

class a_class
{
    public:
        std::vector<a_struct>   the_structs;
        a_class()                       {Init();}
        a_class(a_class const & origin) {Init();}
        void Init()
        {
            the_structs.resize(10); 
            for(int q=0; q<10; q++)
                the_structs[q] = a_struct(7);
        }
};
struct a_struct
{
向量动态数组;
结构(int-length):动态数组(length){
a_struct():动态_数组(){}
};
甲级
{
公众:
std::向量_结构;
_类(){Init();}
a_类(a_类常量和原点){Init();}
void Init()
{
结构调整(10);

对于(intq=0;q而言,问题在于您正试图进行自己的内存管理

使用内置容器:

struct a_struct
{
    std::vector<int>    dynamic_array;
    a_struct(int length) : dynamic_array(length){}
    a_struct()           : dynamic_array() {}
};

class a_class
{
    public:
        std::vector<a_struct>   the_structs;
        a_class()                       {Init();}
        a_class(a_class const & origin) {Init();}
        void Init()
        {
            the_structs.resize(10); 
            for(int q=0; q<10; q++)
                the_structs[q] = a_struct(7);
        }
};
struct a_struct
{
向量动态数组;
结构(int-length):动态数组(length){
a_struct():动态_数组(){}
};
甲级
{
公众:
std::向量_结构;
_类(){Init();}
a_类(a_类常量和原点){Init();}
void Init()
{
结构调整(10);

对于(int q=0;q你说的正确是什么意思?我真的不希望在调用复制构造函数时复制任何内容。@马特:阅读我给出的关于3的规则的链接。你说的正确是什么意思?我真的不希望在调用复制构造函数时复制任何内容。@马特:阅读我给出的关于3.PS规则的链接。NUL的测试析构函数中的L是浪费时间。在NULL上调用delete是完全有效的。值得使用valgrind来帮助跟踪此类问题。它将告诉您内存被删除的位置以及内存被删除的位置