动态3d数组的声明和赋值
Declaration and assignation of dynamic 3d array
我已经为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;
}
您已经动态分配了内存,但是您没有遵循三的规则。您缺少一个赋值操作符,所以当您这样做时:
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
死亡时,它会尝试重新分配相同的内存。此外,在第二行之后对该内存的任何访问都是未定义的行为。
这是一个微不足道的打字错误。我来指出这行,并让您指出错误的地方:
for (j=0;j<M;i++)
也就是说,除了缺少赋值操作符,它使n = Grid3d(2,2,2);
中的原始构造对象被释放,因此您正在使用NULL指针访问operator()
中的G[i][j][k]
。
相关文章:
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- 如何在 c++ 中正确声明/赋值变量的值
- 在C++中用字符串数组拆分声明和赋值
- 如何声明一个数组,然后在另一行中赋值
- 如何声明可以执行赋值操作的函数?(C++)
- 使赋值运算符在声明上工作
- 在声明上为类赋值不会编译
- 未隐式声明的移动赋值运算符
- 将默认赋值运算符声明为 constexpr:哪个编译器是正确的?
- C++重载赋值运算符声明中做什么?
- 用c++赋值内联声明变量
- 在C++中为类变量赋值后声明类变量
- 指针声明基础(多维数组指针的赋值)
- 稍后声明数组并赋值
- 如何使用const_reference类型来声明一个变量并为其赋值 front() 函数的返回值
- 如果我们只定义复制构造函数/oper=,为什么移动构造函数/move赋值没有隐式声明和定义为删除
- 为什么引用类型成员会导致删除隐式声明的复制赋值运算符
- 在同一语句中编写引用声明和赋值
- 使用"using"声明隐藏基类方法不适用于赋值运算符
- 用花括号代替赋值操作符声明和实例化作用域变量