我为3d数组创建了下一个类。将变量声明为例如
Grid3d n = Grid3d(2,2,2);
n(0,0,0) = 1;
工作正常,但声明为
Grid3d n;
n = Grid3d(2,2,2);
n(0,0,0) = 1;
给我一个分段错误,问题似乎是默认的构造函数,但我不知道如何解决它,任何线索?
#ifndef _GRID3D_
#define _GRID3D_
#include <iostream>
#include <cmath>
#include <cassert> // assert()
using namespace std;
class Grid3d
{
private:
int L;
int M;
int N;
double *** G;
public:
Grid3d(int,int,int);
Grid3d();
Grid3d(const Grid3d &);
~Grid3d();
double & operator()(int,int,int);
};
#endif
//Constructor
Grid3d::Grid3d(int L,int M,int N)
:L(L), M(M), N(N)
{
int i,j,k;
G = new double ** [L];
for (i=0;i<L;i++){
G[i] = new double * [M];
for (j=0;j<M;j++){
G[i][j] = new double [N];
for (k=0;k<N;k++){
G[i][j][k] = 0;
}
}
}
}
//Constructor vacío
Grid3d::Grid3d()
:L(0), M(0), N(0)
{
G = NULL;
}
//Constructor copia
Grid3d::Grid3d(const Grid3d &A)
:L(A.L), M(A.M), N(A.N)
{
G = new double ** [L];
int i,j,k;
for (i=0;i<L;i++){
G[i] = new double * [M];
for (j=0;j<M;i++){
G[i][j] = new double [N];
for (k=0;k<N;k++){
G[i][j][k] = A.G[i][j][k];
}
}
}
}
//Destructor
Grid3d::~Grid3d()
{
// Libera memoria
for (int i=0;i<L;i++){
for (int j=0;j<M;j++){
delete [] G[i][j];
G[i][j] = NULL;
}
delete [] G[i];
G[i] = NULL;
}
delete G;
G = NULL;
}
double& Grid3d::operator()(int i,int j,int k)
{
assert(i >= 0 && i < L);
assert(j >= 0 && j < M);
assert(k >= 0 && k < N);
return G[i][j][k];
}
作业运算符
Grid3d Grid3d::operator = (const Grid3d &A)
{
if (this == &A) {return *this;};
if (G != NULL){
// Libera memoria
for (int i=0;i<L;i++){
for (int j=0;j<M;j++){
delete [] G[i][j];
G[i][j] = NULL;
}
delete [] G[i];
G[i] = NULL;
}
delete G;
G = NULL;
}
L = A.L;
M = A.M;
N = A.N;
G = new double ** [L];
int i,j,k;
for (i=0;i<L;i++){
G[i] = new double * [M];
for (j=0;j<M;i++){
G[i][j] = new double [N];
for (k=0;k<N;k++){
G[i][j][k] = A.G[i][j][k];
}
}
}
return *this;
}
答案 0 :(得分:2)
这是一个微不足道的错字。我会指出这条线,我会让你发现它出错的地方:
for (j=0;j<M;i++)
也就是说,除了缺少赋值运算符之外,它使n = Grid3d(2,2,2);
中的原始构造对象被释放,因此您使用NULL指针访问G[i][j][k]
中的operator()
。
答案 1 :(得分:2)
您已动态分配内存,但未遵循rule of three。您缺少一个赋值运算符,所以当您这样做时:
Grid3d n;
n = Grid3d(2,2,2); // both RHS temporary and n point to the same data.
n(0,0,0) = 1; // Accessing deleted memory: undefined behaviour.
您将尝试对同一内存进行两次取消分配,因为您的n
指针指向与第二行中分配给它的临时内存相同的内存。当临时死亡时,它会取消分配它的内存。当n
死亡时,它会尝试取消分配相同的内存。此外,在第二行之后对该内存的任何访问都是未定义的行为。