我有两个简单的课程。当A类中有一个空析构函数(空~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;
}
答案 0 :(得分:2)
您的复制构造函数首先使用新的n
覆盖旧n
,然后尝试删除旧数组的n
元素。但是如果阵列的大小不同呢? 循环后覆盖n
。
或者,更好的是,摆脱这个可怕的指针怪物并改为使用std::vector
。
答案 1 :(得分:1)
首先,你违反了“三规则”(在任何分配内存的类中,你需要一个复制构造函数和赋值运算符,以适当的方式“处理”分配的内存)。
在“数组”为NULL的情况下,析构函数也会被破坏 - 在运行循环以删除内部部分之前,需要检查该数组是否为NULL。