C++ 尝试处理嵌套对象/结构时出现内存泄漏或内存错误&;动态数组。可能的Xcode/malloc问题
当我用Xcode编译并运行它时,我得到了错误,至少连续100次,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 <
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 ctor
{
do_copy(copy);
}
a_struct& operator = (const a_struct ©) // <<--- 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 ©)
{
// 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 ctor
{
do_copy(copy);
}
a_struct& operator = (const a_struct ©) // <<--- 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 ©)
{
// 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来帮助跟踪此类问题。它将告诉您内存被删除的位置以及内存被删除的位置