如何为二维数组分配内存?

问题描述 投票:0回答:6

如何使用“new”运算符声明二维数组?我的书上是这么说的:

int (*p)[4];
p=new[3][4];

但这对我来说没有意义。 p 是一个指向 4 个 int 数组的指针,那么如何使其指向 2d 数组呢?

c++ arrays new-operator dynamic-arrays
6个回答
11
投票

看来你需要指针到指针。编辑:嗯,更准确地说,以下示例创建指向数组的指针数组

首先要做:

int **p = new int*[NUM];

您已经创建了指针数组。现在您需要为每个人创建另一个数组。你可以这样做:

for(int i = 0; i < NUM; i++)
{
    p[i] = new int[ANOTHER_NUM];
}

对于释放,你可以做类似的事情,但是以相反的方式:

for(int i = 0; i < NUM; i++)
{
    delete[] p[i];
}

最后:

delete[] p;

现在您可以使用它了。这样你就可以创建N维数组,只需添加更多'*'即可。如果您还有其他具体问题,请在评论中提问。

但是,一般来说,要获得更多信息,我建议您首先尝试 Google 搜索“C++ 中的二维数组”或“C++ 二维数组的动态分配”等问题,即。 e. 此查询


5
投票

其他答案包括为行提供一个指针数组,每行都有一个指向

int
数组的指针。另一种选择是简单地分配一个足够大的一维数组来容纳所有二维数组的元素:

int* p = new int [3 * 4];

然后,您可以使用

p[r][c]
,而不是使用
p[r * kNumCols + c]
语法。在此示例中,
kNumCols = 4
。这通常是 LAPACK 风格的数字运算中所做的,因为它使内存中的内容保持连续,并且您不需要分配这么多内存块。

注意:在实践中,这通常不会比替代方案慢,因为行偏移计算已通过公共子表达式优化移出循环。此外,许多优化器都知道寻找这种模式。此外,通过将数据保留在单个内存块中,数据更有可能保留在缓存中。 在 C++ 中,您可以使用辅助模板类来实现

p[][]

表示法:


template<class T> class Array2DPtrRow {public: Row(T* row_): row(row_) {} operator T*() { return row; } T& operator [](size_t c) { return row[c]; } private: T* row; }; template<class T, size_t NC> class Array2DPtr {public: Array2DPtr(T* buf_): buf(buf_) {} operator T*() { return buf; } Array2DPtrRow<T> operator [](size_t r) { return Array2DPtrRow<T>(buf + NC * r); } private: T* buf; };

这会优化为与上面相同的代码,但允许您使用 
[][]

表示法,并且

要求您在编译时知道数组维度
。使用示例: Array2DPtr<int, 4> p(new int[3 * 4]); p[1][2];

这可以转换为使 NC 成为类成员而不是模板参数,但最终的对象不再只是一个指针:

template<class T> class Array2DPtr {public: Array2DPtr(T* buf_, size_t nc_): buf(buf_), nc(nc_) {} operator T*() { return buf; } Array2DPtrRow<T> operator [](size_t r) { return Array2DPtrRow<T>(buf + nc * r); } private: T* buf; size_t nc; }; Array2DPtr<int> p(new int[3 * 4], 4); p[1][2];

请注意,这些类都不需要复制构造函数、赋值运算符或析构函数,因为它们不像常规指针那样获得所指向内存的所有权。所以要释放内存,你还需要这样做:

delete[] p;

或者如果你的编译器无法弄清楚:

delete[] (int*)p;



3
投票

请记住,数组相当于指向数组第一个元素的指针,因此例如您可以编写:

char str[14] = "Hello, world!"; char *ptr = str;

这也适用于二维数组。

int (*p)[4];

声明一个指向二维数组第一个元素的指针。然后 
p

可以指向任何二维数组,只要它的第二维是 4,所以例如你可以写


int arr[3][4]; int (*p)[4] = arr;

当然你也可以动态分配内存:

int (*p)[4] = new int[3][4];

同样,第二个维度必须为 4,但您可以改变第一个维度。


2
投票

您可以将

p

显式声明为 2D 数组:


int p[3][4]; // All of p resides on the stack.

(请注意,对于基本类型,此处不需要 
new

,除非您使用 C++ 并希望在堆上分配它们。)


或者您可以将其声明为指针向量(一维数组),然后为每个向量分配内存:

int *p[3]; // The vector addresses reside on the stack. for (int i=0; i<3; i++) { p[i] = malloc(4 * sizeof(int)); // Each element resides on the heap. } // You can now access p as p[j][k] as if it were a 2D array. for (int i=0; i<3; i++) { free p[i]; }

或者,如果您不知道任一维度,您可以动态分配整个 2D 数组:

#define WIDTH 3 #define HEIGHT 4 int **p; // Base address resides on the stack. p = malloc(WIDTH * sizeof(int *)); // Pointers to vectors reside on the heap. for (int i=0; i<WIDTH; i++) { p[i] = malloc(HEIGHT * sizeof(int)); // Data values reside on the heap. } // You can now access p as p[j][k] as if it were a 2D array. // Release the memory that was allocated to each vector. for (int i=0; i<WIDTH; i++) { free(p[i]); } // Release the memory that was allocated to the initial pointer. free(p);



1
投票

int **array_ptr; //two * are needed because it is a pointer to a pointer array_ptr=new int*[firstnumber]; //creates a new array of pointers to int objects for(int i=0; i<firstnumber; ++i) array_ptr[i]=new int[secondnumber];



0
投票

std::vector<std::vector<double>> A; A.resize(Col); for(int i=0; i<Col; i++) { A[i].resize(Row); }

© www.soinside.com 2019 - 2024. All rights reserved.