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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10062655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:34:21  来源:igfitidea点击:

How do i allocate memory for a 2d array?

c++arraysnew-operatordynamic-arrays

提问by Nirvan

How do i declare a 2d array using the 'new' operator? My book says this:

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

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

but it doesn't make sense to me. p is a pointer to an array of 4 ints, so how can it be made to point to a 2d array?

但这对我没有意义。p 是一个指向 4 个整数数组的指针,那么如何让它指向一个二维数组呢?

回答by Miroslav Mares

It seems you need pointer to pointer. EDIT: Well, to be more exact, the following example creates an array of pointers to arrays.

看来您需要指向指针的指针。编辑:好吧,更准确地说,以下示例创建了一个指向数组的指针数组

First do:

首先做:

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

Here you've created array of pointers. Now you need to create another array for every of them. That you can do this way:

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

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

For deallocation you do similar, but in reverse way:

对于解除分配,您执行类似的操作,但方式相反:

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

And finally:

最后:

delete[] p;

Now you can work with it. This way you can create N-dimensional array, just add more '*'. If you have any other particular question, ask in the comments, please.

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

But, generally, for further info I recommend you to try Google first with questions like "2D array in C++" or "dynamic allocation of 2D array C++", i. e. this query.

但是,一般来说,为了获得更多信息,我建议您首先尝试使用 Google 解决诸如“C++ 中的二维数组”或“二维数组 C++ 的动态分配”之类的问题,即这个查询

回答by Mike DeSimone

Other answers cover having a pointer array for your rows, with a pointer to an intarray per row. Another option is to simply allocate a 1-D array big enough to hold all the 2-D array's elements:

其他答案包括为您的行设置一个指针int数组,每行都有一个指向数组的指针。另一种选择是简单地分配一个足够大的一维数组来容纳所有二维数组的元素:

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

Then instead of using the p[r][c]syntax, you use p[r * kNumCols + c]. In this example, kNumCols = 4. This is generally what's done in LAPACK-style number crunching, since it keeps things contiguous in memory and you don't need to allocate so many memory blocks.

然后不使用p[r][c]语法,而是使用p[r * kNumCols + c]. 在这个例子中,kNumCols = 4. 这通常是在 LAPACK 风格的数字处理中所做的,因为它使内存中的事物保持连续,并且您不需要分配这么多内存块。

Note: This generally is notslower than the alternative in practice, because the row offset calculation is moved out of the loop by the common subexpression optimization. Also, many optimizers know to look for this pattern. Further, by keeping your data co-located in a single block of memory, the data is more likely to stay in cache.

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

In C++, you could implement the p[][]notation with a helper template class:

在 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;
};

This optimizes down to the same code as above, but allows you to use [][]notation and requires you to know your array dimensions at compile time. Usage example:

这将优化为与上面相同的代码,但允许您使用[][]符号并要求您在编译时知道您的数组维度。用法示例:

Array2DPtr<int, 4> p(new int[3 * 4]);
p[1][2];

This could be converted to make NC into a class member instead of a template parameter, but then the final object isn't just a pointer any more:

这可以转换为使 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];

Note that none of these classes need copy constructors, assignment operators, or destructors because they don't take ownership of the pointed-to memory any more than a regular pointer does. So to release the memory, you still need to do:

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

delete[] p;

Or if your compiler can't figure it out:

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

delete[] (int*)p;

回答by Neil

To actually answer the question:

要实际回答这个问题:

Remember that an array is equivalent to a pointer to the first element of the array, so for instance you can write:

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

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

This works for a two-dimensional array as well.

这也适用于二维数组。

int (*p)[4];

declares a pointer to the first element of a two-dimensional array. pcan then be pointed at any two-dimensional array, as long as its second dimension is 4, so for instance you could write

声明一个指向二维数组第一个元素的指针。p然后可以指向任何二维数组,只要它的第二维是 4,例如你可以写

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

Of course you can also allocate the memory dynamically:

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

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

Again, the second dimension has to be 4, but you can vary the first dimension.

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

回答by Adam Liss

There are several ways to declare multidimensional arrays in C.

在 C 中有几种方法可以声明多维数组。

You can declare pexplicitly as a 2D array:

您可以p显式声明为二维数组:

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

(Note that newisn't required here for basic types unless you're using C++ and want to allocate them on the heap.)

(请注意,new这里不需要基本类型,除非您使用 C++ 并希望在堆上分配它们。)

Or you can declare it as a vector (1D array) of pointers, and then allocate memory for each vector:

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

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];
}

Or, if you don't know either dimension, you can allocate the entire 2D array dynamically:

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

#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);

回答by v01d

You need something like this

你需要这样的东西

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];