c++ - 为什么这个核心转储错误发生在我的课堂上?我已经包含了复制构造函数、复制赋值和析构函数
问题描述
它只是一个二维数组(TwoD)类,其中一个构造函数采用行数和列数,一个重载的赋值运算符和一个重载的非成员 + 运算符作为 TwoD 类的朋友。
更新代码:
#include<iostream>
using namespace std;
class TwoD{
public:
TwoD(){}
~TwoD(){
for(int i=0;i<row;i++){
delete [] arr[i];
}
delete [] arr;
}
TwoD(int r,int c):row(r),col(r){
cout<<"Enter "<<r<<" rows of "<<c<<" doubles each"<<endl;
arr=new double*[row];
for(int i=0;i<r;i++){
arr[i]=new double[c];
for(int j=0;j<c;j++){
cin>>arr[i][j];
}
}
}
TwoD(const TwoD& b){
row=b.row;
col=b.col;
if(b.arr==NULL){
return;
}
arr=new double*[row];
for(int i=0;i<row;i++){
arr[i]=new double[col];
for(int j=0;j<col;j++){
arr[i][j]=b.arr[i][j];
}
}
}
void echo() const{
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
void set(int r,int c,double value){
arr[r][c]=value;
}
const TwoD& operator=(const TwoD& b);
friend const TwoD operator+(const TwoD& a,const TwoD& b);
private:
int row,col;
double** arr=NULL;
};
const TwoD& TwoD::operator=(const TwoD& b){
if(this==&b){
return *this;
}
if(arr!=NULL){
for(int i=0;i<row;i++){
delete [] arr[i];
}
delete [] arr;
}
row=b.row;
col=b.col;
arr=new double*[row];
for(int i=0;i<row;i++){
arr[i]=new double[col];
for(int j=0;j<col;j++){
arr[i][j]=b.arr[i][j];
}
}
return *this;
}
const TwoD operator+(const TwoD& a,const TwoD& b){
TwoD temp(a);
for(int i=0;i<a.row;i++){
for(int j=0;j<a.col;j++){
temp.arr[i][j]+=b.arr[i][j];
}
}
return temp;
}
int main(){
cout<<"Enter the row and column dimensions of the array\n";
int r,c;
cin>>r>>c;
TwoD a(r,c);
cout<<"Echoing the 2 dim. array, matrix1\n";
a.echo();
cout<<"Enter the row and column dimensions of the array\n";
cin>>r>>c;
TwoD b(r,c);
cout<<"Echoing the 2 dim. array, matrix2\n";
b.echo();
TwoD d;
cout<<"Assigning matrix 2 to matrix 3\n";
cout<<"Displaying the 2 dim array, matrix3 resulting from assignment"<<endl;
d=b;
cout<<"Rows "<<r<<" Cols "<<c<<endl;
d.echo();
cout<<"Displaying the 2 dim array, sum of matrix 1 and 2\n";
cout<<"Rows "<<r<<" Cols "<<c<<endl;
(a+b).echo();
return 0;
}
老一:
#include<iostream>
using namespace std;
class TwoD{
public:
TwoD(){}
~TwoD(){
delete [] arr;
}
TwoD(int r,int c):row(r),col(r){
cout<<"Enter "<<r<<" rows of "<<c<<" doubles each"<<endl;
arr=new double*[r];
for(int i=0;i<r;i++){
arr[i]=new double[c];
for(int j=0;j<c;j++){
cin>>arr[i][j];
}
}
}
TwoD(const TwoD& b){
row=b.row;
col=b.col;
for(int i=0;i<row;i++){
arr[i]=new double[col];
for(int j=0;j<col;j++){
arr[i][j]=b.arr[i][j];
}
}
}
void echo() const{
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
void set(int r,int c,double value){
arr[r][c]=value;
}
const TwoD operator=(const TwoD& b);
friend const TwoD operator+(const TwoD& a,const TwoD& b);
private:
int row,col;
double** arr;
};
const TwoD TwoD::operator=(const TwoD& b){
if(this==&b){
return *this;
}
delete [] arr;
row=b.row;
col=b.col;
arr=new double*[row];
for(int i=0;i<row;i++){
arr[i]=new double[col];
for(int j=0;j<col;j++){
arr[i][j]=b.arr[i][j];
}
}
return *this;
}
const TwoD operator+(const TwoD& a,const TwoD& b){
TwoD temp(a);
for(int i=0;i<a.row;i++){
for(int j=0;j<a.col;j++){
temp.arr[i][j]+=b.arr[i][j];
}
}
return temp;
}
int main(){
cout<<"Enter the row and column dimensions of the array\n";
int r,c;
cin>>r>>c;
TwoD a(r,c);
cout<<"Echoing the 2 dim. array, matrix1\n";
a.echo();
cout<<"Enter the row and column dimensions of the array\n";
cin>>r>>c;
TwoD b(r,c);
cout<<"Echoing the 2 dim. array, matrix2\n";
b.echo();
TwoD d;
cout<<"Assigning matrix 2 to matrix 3\n";
cout<<"Displaying the 2 dim array, matrix3 resulting from assignment"<<endl;
d=b;
cout<<"Rows "<<r<<" Cols "<<c<<endl;
d.echo();
cout<<"Displaying the 2 dim array, sum of matrix 1 and 2\n";
cout<<"Rows "<<r<<" Cols "<<c<<endl;
(a+b).echo();
return 0;
}
预期输出:
echo() 成员函数也是错误的(我不知道为什么),但我想先关注核心转储,这甚至意味着什么?
解决方案
崩溃最有可能发生,因为在复制构造函数中您没有为arr
自己分配内存。
当你这样做时
arr[i]=new double[col];
那么该变量arr
未初始化并且将无效。这会调用未定义的行为,并且可能会导致崩溃。
您需要先为arr
自己分配内存:
arr=new double*[row];
然而,还有另一个可能导致崩溃的原因,那是因为默认构造函数对象将具有未初始化的成员变量。
如果将这种默认构造的对象用作复制操作的源,那么您将使用这些未初始化的值,这将导致未定义的行为和可能的崩溃。
即使您正确初始化变量,您也需要添加检查以确保您没有使用空指针等。