C++ 一种动态分配多维数组的方法

C++ 一种动态分配多维数组的方法,c++,pointers,multidimensional-array,C++,Pointers,Multidimensional Array,敬礼 我在一本书中学习了多维数组的动态分配,我找到了一些方法,现在已经没有问题了。 但这本书的作者向我们展示了一种方法,但它并不正确。这是: pbeans = new double [3][4]; // Allocate memory for a 3x4 array 这就是错误: error C2440: '=' : cannot convert from 'int (*)[4]' to 'int *' 我应该如何定义pbeans(如果这种类型的编码是合法的) 到底是什么问题

敬礼

我在一本书中学习了多维数组的动态分配,我找到了一些方法,现在已经没有问题了。 但这本书的作者向我们展示了一种方法,但它并不正确。这是:

pbeans = new double [3][4];         // Allocate memory for a 3x4 array
这就是错误:

error C2440: '=' : cannot convert from 'int (*)[4]' to 'int *'
我应该如何定义pbeans(如果这种类型的编码是合法的)

到底是什么问题


注意。

您需要分别分配数组的每个维度:

double **pbeans = new double*[3];
for (int i = 0; i < 3; ++i) {
    pbeans[i] = new double[4];
}
double**pbeans=newdouble*[3];
对于(int i=0;i<3;++i){
pbeans[i]=新的双精度[4];
}

以下是一种在堆上连续分配内存的方法:

typedef double MyGrid[3][4];

int main(int argc, char* argv[])
{
    MyGrid& x = *(reinterpret_cast<Grid*>(new double[12]));
    ...
    x[1][2] = 0.3333;
    ...
    delete[] &x;
    return 0;
}
typedef-double-MyGrid[3][4];
int main(int argc,char*argv[])
{
MyGrid&x=*(重新解释铸造(新双[12]);
...
x[1][2]=0.3333;
...
删除[]&x;
返回0;
}
您可以轻松地将其转化为更通用的解决方案:

template<typename T, int x, int y>
struct Array2D
{
    typedef T CArrayType[x][y];
    typedef CArrayType& RefType;
    static CArrayType& New()
    {
        return *(reinterpret_cast<CArrayType*>(new T[x * y]));
    }
    static void Delete(RefType x)
    {
        delete[] &x;
    }
};

typedef Array2D<double, 3, 4> MyGrid;// define your 2d array with 3 rows / 4 columns.

int main(int argc, char* argv[])
{
    MyGrid::RefType j = MyGrid::New();
    ...
    j[1][2] = 0.3333;
    ...
    MyGrid::Delete(j);
    return 0;
}
模板
结构阵列2d
{
typedef T CArrayType[x][y];
typedef CArrayType和RefType;
静态CArrayType&New()
{
返回*(重新解释铸造(新T[x*y]);
}
静态空心删除(参照类型x)
{
删除[]&x;
}
};
typedef Array2D MyGrid;//用3行/4列定义二维阵列。
int main(int argc,char*argv[])
{
MyGrid::RefType j=MyGrid::New();
...
j[1][2]=0.3333;
...
MyGrid::删除(j);
返回0;
}
其思想是只生成一维(x*y)的元素,并将其转换为二维数组。但由于数组类型是值类型,所以需要处理指向数组的指针。使用引用使其几乎透明

Boost可能有类似的功能,但我对Boost了解不够,无法说…

我的:

对于“C声明程序”,您可以使用typedef使其更具可读性:

typedef double row[4];

row *pbeans;
pbeans = new row[3];

// ...

delete[] pbeans;
<>但是在C++中,我们更喜欢RAI容器,而不是原始指针:

#include <vector>
#include <array>

std::vector<std::array<double, 4> > beans(3);
#包括
#包括
std::向量bean(3);

请注意,完全没有
delete[]
,这使得此解决方案异常安全。

谢谢,因此这是非法的,我应该将书放入回收站吗?(:你可以说
double-pbeans[3][4]
,但这将在堆栈而不是堆上创建变量。实际上,您可以动态创建多维数组,而无需单独分配每个维度。请参见我的答案。@C77431:与Alnitak的答案不同,这将在内存中连续分配多维数组。这可能是您想要的,也可能不是您想要的。无需强制转换,请参阅我的答案。您可能会发现(以及紧接着的常见问题解答)有助于理解这一点。顺便说一句,了解这一点是件好事,但一般来说,您应该只使用容器类(例如,标准模板库)。如果您确实使用
new
,您通常会希望将其包装在容器类中,或者至少使用智能指针。Tenfour的代码看起来比Alnitak的更复杂,因为它更适合生产;它通过我更喜欢这种方法保护您不受内存泄漏的影响,因为它还可以非常清楚地显示您的维度。@C77:否请注意,原始错误消息已提示pbeans所需的类型:
int(*)[4]
。只是许多程序员不知道这种有趣的令牌组合可能意味着什么。诅咒你,C声明程序语法!如果值是静态的,那么new/delete就没有新的。如果两者都是动态的,你需要分别取消分配每一行,请参见此处的p2DArray示例:
#include <vector>
#include <array>

std::vector<std::array<double, 4> > beans(3);