在析构函数中释放内存时出现segfault
Seg fault when deallocating memory in destructor
有两个简单的类。当我在类(empty ~A(){};)中有一个空析构函数时,一切都很好。当我添加两行来释放一个数组时,我的程序给了我分段错误。
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class A
{
private :
int n;
int m;
int **array;
public :
A();
A(int nn, int mm);
A(const A& a);
A& operator=(A a);
int getAt(int i, int j);
int getN(){return n;}
int getM(){return m;}
~A();
};
A::A()
{
n = 0;
m = 0;
array = NULL;
}
A::A(int nn, int mm)
{
n = nn;
m = mm;
array = new int*[n];
for(int i = 0; i <n; i++)
array[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
array[i][j] = rand()%2;
}
A::A(const A& a)
{
for(int i=0; i <n; i++)
delete[] array[i];
delete [] array;
array = NULL;
n = a.n;
m = a.m;
array = new int*[n];
for(int i = 0; i <n; i++)
array[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
array[i][j] = a.array[i][j];
}
A& A::operator=(A a)
{
for(int i=0; i <n; i++)
delete[] array[i];
delete [] array;
array = NULL;
n = a.n;
m = a.m;
array = new int*[n];
for(int i = 0; i <n; i++)
array[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
array[i][j] = a.array[i][j];
return *this;
}
int A::getAt(int i, int j)
{
return array[i][j];
}
A::~A()
{
for(int i=0; i <n; i++)
delete[] array[i];
delete [] array;
array = NULL;
}
class B
{
private :
A a;
public :
B(){}
B(A aa);
void setA(A aa);
void showA();
};
B::B(A aa)
{
a = aa;
}
void B::setA(A aa)
{
a = aa;
}
void B::showA()
{
int n = a.getN();
int m = a.getM();
for(int i=0; i<n; i++){
for(int j=0; j<m; j++)
cout << a.getAt(i,j) << " ";
cout << "n";
}
cout << "n";
}
int main()
{
A a(3, 4);
B b(a);
b.showA();
return 0;
}
如何解决这个问题?为什么会发生这种情况?
解决:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class A
{
private :
int n;
int m;
int **array;
public :
A();
A(int nn, int mm);
A(const A& a);
A& operator=(const A& a);
int getAt(int i, int j);
int getN(){return n;}
int getM(){return m;}
~A();
};
A::A()
{
n = 0;
m = 0;
array = NULL;
}
A::A(int nn, int mm)
{
n = nn;
m = mm;
array = new int*[n];
for(int i = 0; i <n; i++)
array[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
array[i][j] = rand()%2;
}
A::A(const A& a)
{
n = a.n;
m = a.m;
array = new int*[n];
for(int i = 0; i <n; i++)
array[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
array[i][j] = a.array[i][j];
}
A& A::operator=(const A& a)
{
for(int i=0; i <n; i++)
delete[] array[i];
delete [] array;
array = NULL;
n = a.n;
m = a.m;
array = new int*[n];
for(int i = 0; i <n; i++)
array[i] = new int[m];
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
array[i][j] = a.array[i][j];
return *this;
}
int A::getAt(int i, int j)
{
return array[i][j];
}
A::~A()
{
for(int i=0; i <n; i++)
delete[] array[i];
delete [] array;
array = NULL;
}
class B
{
private :
A a;
public :
B(){}
B(A aa);
void setA(A aa);
void showA();
};
B::B(A aa)
{
a = aa;
}
void B::setA(A aa)
{
a = aa;
}
void B::showA()
{
int n = a.getN();
int m = a.getM();
for(int i=0; i<n; i++){
for(int j=0; j<m; j++)
cout << a.getAt(i,j) << " ";
cout << "n";
}
cout << "n";
}
int main()
{
A a(3, 4);
B b(a);
b.showA();
return 0;
}
您的复制构造函数首先用新的n
覆盖旧的n
,然后尝试删除旧数组的n
元素。但是如果数组的大小不同呢?覆盖循环后的n
或者,更好的是,摆脱这个可怕的指针怪物,使用std::vector
代替。
首先,您违反了"三原则"(在任何分配内存的类中,都需要有一个复制构造函数和赋值操作符,以适当的方式"处理"分配的内存)。
你的析构函数在"数组"为NULL的情况下也会失效——你需要在运行循环删除内部部分之前检查数组是否为NULL。
相关文章:
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- C++中带有List类的迭代器Segfault
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 检查nullptr是否100%保护内存布局不受segfault影响
- 如何使用Cuda避免segfault上的内存泄漏
- 在析构函数中释放内存时出现segfault