如何使用C中的动态多维数组?

时间:2021-09-03 21:34:15

Does someone know how I can use dynamically allocated multi-dimensional arrays using C? Is that possible?

有人知道如何使用C动态地分配多维数组吗?这有可能吗?

9 个解决方案

#1


73  

With dynamic allocation, using malloc:

动态分配,使用malloc:

int** x;

x = malloc(dimension1_max * sizeof(int*));
for (int i = 0; i < dimension1_max; i++) {
  x[i] = malloc(dimension2_max * sizeof(int));
}

[...]

for (int i = 0; i < dimension1_max; i++) {
  free(x[i]);
}
free(x);

This allocates an 2D array of size dimension1_max * dimension2_max. So, for example, if you want a 640*480 array (f.e. pixels of an image), use dimension1_max = 640, dimension2_max = 480. You can then access the array using x[d1][d2] where d1 = 0..639, d2 = 0..479.

这分配了一个二维数组大小的尺寸。例如,如果您想要一个640*480的数组(如图像的f.e.像素),请使用维度1_max = 640,维度2_max = 480。然后,您可以使用x[d1][d2]访问数组,其中d1 = 0。639年,d2 = 0 . . 479。

But a search on SO or Google also reveals other possibilities, for example in this SO question

但是,对SO或谷歌的搜索也揭示了其他的可能性,例如在这个问题中。

Note that your array won't allocate a contiguous region of memory (640*480 bytes) in that case which could give problems with functions that assume this. So to get the array satisfy the condition, replace the malloc block above with this:

注意,在这种情况下,您的数组不会分配一个连续的内存区域(640*480字节),这可能会给假定这个的函数带来问题。为了使数组满足条件,用这个替换上面的malloc块:

int** x;
int* temp;

x = malloc(dimension1_max * sizeof(int*));
temp = malloc(dimension1_max * dimension2_max * sizeof(int));
for (int i = 0; i < dimension1_max; i++) {
  x[i] = temp + (i * dimension2_max);
}

[...]

free(temp);
free(x);

#2


67  

Since C99, 13 years now, C has 2D arrays with dynamical bounds. If you want to avoid that such beast are allocated on the stack (which you should), you can allocate them easily in one go as the following

自C99, 13年以来,C有了具有动态边界的二维数组。如果您想要避免在堆栈上分配这类动物(您应该这样做),您可以在一个go中轻松地分配它们,如下所示。

double (*A)[n] = malloc(sizeof(double[n][n]));

and that's it. You can then easily use it as you are used for 2D arrays with something like A[i][j]. And don't forget that one at the end

就是这样。然后你就可以很容易地使用它,就像你在2D数组中使用类似[i][j]那样的东西。别忘了最后一个。

free(A);

Randy Meyers wrote series of articles explaining variable length arrays (VLAs).

兰迪·迈耶斯(Randy Meyers)写了一系列解释可变长数组(VLAs)的文章。

#3


49  

Basics

Arrays in c are declared and accessed using the [] operator. So that

使用[]操作符声明和访问c中的数组。这

int ary1[5];

declares an array of 5 integers. Elements are numbered from zero so ary1[0] is the first element, and ary1[4] is the last element. Note1: There is no default initialization, so the memory occupied by the array may initially contain anything. Note2: ary1[5] accesses memory in an undefined state (which may not even be accessible to you), so don't do it!

声明一个5个整数的数组。元素的编号为0,所以ary1[0]是第一个元素,而ary1[4]是最后一个元素。Note1:没有默认的初始化,因此数组所占用的内存最初可能包含任何内容。Note2: ary1[5]以未定义的状态访问内存(甚至可能无法访问),所以不要这样做!

Multi-dimensional arrays are implemented as an array of arrays (of arrays (of ... ) ). So

多维数组被实现为数组的数组(数组(…))。所以

float ary2[3][5];

declares an array of 3 one-dimensional arrays of 5 floating point numbers each. Now ary2[0][0] is the first element of the first array, ary2[0][4] is the last element of the first array, and ary2[2][4] is the last element of the last array. The '89 standard requires this data to be contiguous (sec. A8.6.2 on page 216 of my K&R 2nd. ed.) but seems to be agnostic on padding.

声明一个数组的3个一维数组的5个浮点数。现在ary2[0][0]是第一个数组的第一个元素,ary2[0][4]是第一个数组的最后一个元素,而ary2[2][4]是最后一个数组的最后一个元素。89标准要求这些数据是连续的(sec. A8.6.2,在我的K&R 2的第216页)。但在填充物上似乎是不可知论者。

Trying to go dynamic in more than one dimension

If you don't know the size of the array at compile time, you'll want to dynamically allocate the array. It is tempting to try

如果在编译时不知道数组的大小,则需要动态地分配数组。这是很诱人的尝试。

double *buf3;
buf3 = malloc(3*5*sizeof(double));
/* error checking goes here */

which should work if the compiler does not pad the allocation (stick extra space between the one-dimensional arrays). It might be safer to go with:

如果编译器没有对分配进行填充(在一维数组之间添加额外的空间),那么这应该起作用。这样做可能更安全:

double *buf4;
buf4 = malloc(sizeof(double[3][5]));
/* error checking */

but either way the trick comes at dereferencing time. You can't write buf[i][j] because buf has the wrong type. Nor can you use

但不管怎样,这个技巧都是在取消时间的时候出现的。你不能写buf[i][j],因为buf有错误的类型。你也不能使用

double **hdl4 = (double**)buf;
hdl4[2][3] = 0; /* Wrong! */

because the compiler expects hdl4 to be the address of an address of a double. Nor can you use double incomplete_ary4[][]; because this is an error;

因为编译器期望hdl4是双精度地址的地址。也不能使用double incomplete_ary4[][];因为这是一个错误;

So what can you do?

那么你能做什么呢?

  • Do the row and column arithmetic yourself
  • 你自己做行和列算术吗?
  • Allocate and do the work in a function
  • 在一个函数中分配和执行工作。
  • Use an array of pointers (the mechanism qrdl is talking about)
  • 使用一组指针(机制qrdl正在讨论)

Do the math yourself

Simply compute memory offset to each element like this:

简单地计算每个元素的内存偏移量:

  for (i=0; i<3; ++i){
     for(j=0; j<3; ++j){
        buf3[i * 5 + j] = someValue(i,j); /* Don't need to worry about 
                                             padding in this case */
     }
  }

Allocate and do the work in a function

Define a function that takes the needed size as an argument and proceed as normal

定义一个函数,它将所需的大小作为参数,并按照正常进行。

void dary(int x, int y){
  double ary4[x][y];
  ary4[2][3] = 5;
}

Of course, in this case ary4 is a local variable and you can not return it: all the work with the array must be done in the function you call of in functions that it calls.

当然,在本例中,ary4是一个局部变量,您不能返回它:所有与数组相关的工作都必须在函数调用的函数中完成。

An array of pointers

Consider this:

考虑一下:

double **hdl5 = malloc(3*sizeof(double*));
/* Error checking */
for (i=0; i<3; ++i){
   hdl5[i] = malloc(5*sizeof(double))
   /* Error checking */
}

Now hdl5 points to an array of pointers each of which points to an array of doubles. The cool bit is that you can use the two-dimensional array notation to access this structure---hdl5[0][2] gets the middle element of the first row---but this is none-the-less a different kind of object than a two-dimensional array declared by double ary[3][5];.

现在,hdl5指向一个指针数组,每个指针指向一个双打数组。很酷的一点是,你可以使用二维数组表示法来访问这个结构——-hdl5[0][2]得到第一行的中间元素——但这是一种不同的对象,而不是双ary[3][5]所声明的二维数组。

This structure is more flexible then a two dimensional array (because the rows need not be the same length), but accessing it will generally be slower and it requires more memory (you need a place to hold the intermediate pointers).

这个结构更灵活,然后是一个二维数组(因为行不需要相同的长度),但是访问它通常会比较慢,而且需要更多的内存(需要一个位置来保存中间指针)。

Note that since I haven't setup any guards you'll have to keep track of the size of all the arrays yourself.

请注意,由于我没有设置任何守卫,所以您必须自己跟踪所有数组的大小。

Arithmetic

c provides no support for vector, matrix or tensor math, you'll have to implement it yourself, or bring in a library.

c不支持向量、矩阵或张量数学,你必须自己实现它,或者引入一个库。

Multiplication by a scaler and addition and subtraction of arrays of the same rank are easy: just loop over the elements and perform the operation as you go. Inner products are similarly straight forward.

一个标量的乘法运算和加法和减法都很简单:只需对元素进行循环,然后执行操作。内部产品同样是直接的。

Outer products mean more loops.

外部产品意味着更多的循环。

#4


9  

If you know the number of columns at compile time, it's pretty simple:

如果您知道编译时的列数,很简单:

#define COLS ...
...
size_t rows;
// get number of rows
T (*ap)[COLS] = malloc(sizeof *ap * rows); // ap is a *pointer to an array* of T

You can treat ap like any 2D array:

你可以像对待任何2D数组一样对待ap:

ap[i][j] = x;

When you're done you deallocate it as

当你完成之后,你会把它重新分配。

free(ap);

If you don't know the number of columns at compile time, but you're working with a C99 compiler or a C2011 compiler that supports variable-length arrays, it's still pretty simple:

如果您不知道编译时的列数,但是您使用的是C99编译器或支持可变长度数组的C2011编译器,它仍然非常简单:

size_t rows;
size_t cols;
// get rows and cols
T (*ap)[cols] = malloc(sizeof *ap * rows);
...
ap[i][j] = x;
...
free(ap);

If you don't know the number of columns at compile time and you're working with a version of C that doesn't support variable-length arrays, then you'll need to do something different. If you need all of the elements to be allocated in a contiguous chunk (like a regular array), then you can allocate the memory as a 1D array, and compute a 1D offset:

如果您不知道编译时的列数,并且您正在使用一个不支持可变长度数组的C版本,那么您将需要做一些不同的事情。如果您需要将所有元素分配到一个连续的块中(像一个常规数组),那么您可以将内存分配为一维数组,并计算1D偏移量:

size_t rows, cols;
// get rows and columns
T *ap = malloc(sizeof *ap * rows * cols);
...
ap[i * rows + j] = x;
...
free(ap);

If you don't need the memory to be contiguous, you can follow a two-step allocation method:

如果您不需要内存是连续的,您可以采用两步分配方法:

size_t rows, cols;
// get rows and cols
T **ap = malloc(sizeof *ap * rows);
if (ap)
{
  size_t i = 0;
  for (i = 0; i < cols; i++)
  {
    ap[i] = malloc(sizeof *ap[i] * cols);
  }
}

ap[i][j] = x;

Since allocation was a two-step process, deallocation also needs to be a two-step process:

由于分配是两个步骤的过程,所以deallocation也需要一个两步的过程:

for (i = 0; i < cols; i++)
  free(ap[i]);
free(ap);

#5


0  

malloc will do.

malloc。

 int rows = 20;
 int cols = 20;
 int *array;

  array = malloc(rows * cols * sizeof(int));

Refer the below article for help:-

参考下面的文章寻求帮助:-。

http://courses.cs.vt.edu/~cs2704/spring00/mcquain/Notes/4up/Managing2DArrays.pdf

http://courses.cs.vt.edu/ cs2704 spring00 / / Managing2DArrays.pdf mcquain / Notes / 4

#6


-1  

There's no way to allocate the whole thing in one go. Instead, create an array of pointers, then, for each pointer, create the memory for it. For example:

没有办法一次性全部分配。相反,创建一个指针数组,然后,为每个指针创建内存。例如:

int** array;
array = (int**)malloc(sizeof(int*) * 50);
for(int i = 0; i < 50; i++)
    array[i] = (int*)malloc(sizeof(int) * 50);

Of course, you can also declare the array as int* array[50] and skip the first malloc, but the second set is needed in order to dynamically allocate the required storage.

当然,您也可以将数组声明为int* array[50],并跳过第一个malloc,但是为了动态地分配所需的存储,需要第二个设置。

It is possible to hack a way to allocate it in a single step, but it would require a custom lookup function, but writing that in such a way that it will always work can be annoying. An example could be L(arr,x,y,max_x) arr[(y)*(max_x) + (x)], then malloc a block of 50*50 ints or whatever and access using that L macro, e.g.

可以使用一种方法将其分配到单个步骤中,但是它需要一个定制的查找功能,但是以这样一种方式来编写它总是会很烦人。一个例子可以是L(arr,x,y,max_x) arr[(y)*(max_x) + (x)],然后是malloc (50*50 int),或者任何使用L宏的访问权限。

#define L(arr,x,y,max_x) arr[(y)*(max_x) + (x)]

int dim_x = 50;
int dim_y = 50;

int* array = malloc(dim_x*dim_y*sizeof(int));

int foo = L(array, 4, 6, dim_x);

But that's much nastier unless you know the effects of what you're doing with the preprocessor macro.

但是,除非您知道使用预处理器宏所做的工作的影响,否则会更糟糕。

#7


-1  

Here is working code that defines a subroutine make_3d_array to allocate a multidimensional 3D array with N1, N2 and N3 elements in each dimension, and then populates it with random numbers. You can use the notation A[i][j][k] to access its elements.

下面是定义子例程make_3d_array的工作代码,用于在每个维度中分配一个具有N1、N2和N3元素的多维3D数组,然后用随机数填充它。你可以用A[i][j][k]来访问它的元素。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


// Method to allocate a 2D array of floats
float*** make_3d_array(int nx, int ny, int nz) {
    float*** arr;
    int i,j;

    arr = (float ***) malloc(nx*sizeof(float**));

    for (i = 0; i < nx; i++) {
        arr[i] = (float **) malloc(ny*sizeof(float*));

        for(j = 0; j < ny; j++) {
            arr[i][j] = (float *) malloc(nz * sizeof(float));
        }
    }

    return arr;
} 



int main(int argc, char *argv[])
{
    int i, j, k;
    size_t N1=10,N2=20,N3=5;

    // allocates 3D array
    float ***ran = make_3d_array(N1, N2, N3);

    // initialize pseudo-random number generator
    srand(time(NULL)); 

    // populates the array with random numbers
    for (i = 0; i < N1; i++){
        for (j=0; j<N2; j++) {
            for (k=0; k<N3; k++) {
                ran[i][j][k] = ((float)rand()/(float)(RAND_MAX));
            }
        }
   }

    // prints values
    for (i=0; i<N1; i++) {
        for (j=0; j<N2; j++) {
            for (k=0; k<N3; k++) {
                printf("A[%d][%d][%d] = %f \n", i,j,k,ran[i][j][k]);
            }
        }
    }

    free(ran);
}

#8


-2  

int rows, columns;
/* initialize rows and columns to the desired value */

    arr = (int**)malloc(rows*sizeof(int*));
        for(i=0;i<rows;i++)
        {
            arr[i] = (int*)malloc(cols*sizeof(int));
        }

#9


-6  

Why, colleagues, nobody revealed the fact that no exact solution exists in the realm of C? but only in C++ (by exact I mean that above and other site's solutions differ from true C-multidimentional arrays with: aditional entities and so additional memory, etc).

为什么,同事们,没有人发现在C领域没有确切的解决方案?但只有在c++中(我的意思是,上面和其他站点的解决方案不同于真正的C-多维数组:传统实体和额外的内存等等)。

In C++ you must implement (just several lines of code):

在c++中,你必须实现(仅仅几行代码):

typedef double T;
class Matrix2D
{
public:
    Matrix2D(int, int);
   ~Matrix2D();
    T* operator[](int);
private:
    T* const  memory;
    const int rows;
    const int cols;
};

Matrix2D::Matrix2D(int r, int c) : rows(r), cols(c), memory(new T[r*c]) {}
Matrix2D::~Matrix2D() { delete[]  memory; }
T* Matrix2D::operator[](int row) {  return memory + cols*row;}

That's all for those who use code like this: a[i][j].

这都是为那些使用这样的代码的人所做的:a[i][j]。

But for exact similarity with C-multidimensional arrays that class (Matrix2D) lacks double-pointer arithmetics, to be used like this: (*(a+i))[j]. That is not difficult: implement inner clsss "doublePointer" with arithmetics and dereference operators. But I'd rather implemented sort of iterator for such purposes (to step from row to row).

但是,与c -多维数组的完全相似(Matrix2D)缺少双指针算术,可以这样使用:(*(a+i))[j]。这并不困难:用算术和引用运算符来实现内部clsss“doublePointer”。但是,为了达到这样的目的,我宁愿实现类似的迭代器(从行到行)。

More than 2 dimensions? You just need inner classes that implement corresponding operator[]...[] of (n-1)-dimension. Alas, routine..

二维多?您只需要实现相应操作符的内部类[]…[](n - 1)维度。唉,常规的. .

#1


73  

With dynamic allocation, using malloc:

动态分配,使用malloc:

int** x;

x = malloc(dimension1_max * sizeof(int*));
for (int i = 0; i < dimension1_max; i++) {
  x[i] = malloc(dimension2_max * sizeof(int));
}

[...]

for (int i = 0; i < dimension1_max; i++) {
  free(x[i]);
}
free(x);

This allocates an 2D array of size dimension1_max * dimension2_max. So, for example, if you want a 640*480 array (f.e. pixels of an image), use dimension1_max = 640, dimension2_max = 480. You can then access the array using x[d1][d2] where d1 = 0..639, d2 = 0..479.

这分配了一个二维数组大小的尺寸。例如,如果您想要一个640*480的数组(如图像的f.e.像素),请使用维度1_max = 640,维度2_max = 480。然后,您可以使用x[d1][d2]访问数组,其中d1 = 0。639年,d2 = 0 . . 479。

But a search on SO or Google also reveals other possibilities, for example in this SO question

但是,对SO或谷歌的搜索也揭示了其他的可能性,例如在这个问题中。

Note that your array won't allocate a contiguous region of memory (640*480 bytes) in that case which could give problems with functions that assume this. So to get the array satisfy the condition, replace the malloc block above with this:

注意,在这种情况下,您的数组不会分配一个连续的内存区域(640*480字节),这可能会给假定这个的函数带来问题。为了使数组满足条件,用这个替换上面的malloc块:

int** x;
int* temp;

x = malloc(dimension1_max * sizeof(int*));
temp = malloc(dimension1_max * dimension2_max * sizeof(int));
for (int i = 0; i < dimension1_max; i++) {
  x[i] = temp + (i * dimension2_max);
}

[...]

free(temp);
free(x);

#2


67  

Since C99, 13 years now, C has 2D arrays with dynamical bounds. If you want to avoid that such beast are allocated on the stack (which you should), you can allocate them easily in one go as the following

自C99, 13年以来,C有了具有动态边界的二维数组。如果您想要避免在堆栈上分配这类动物(您应该这样做),您可以在一个go中轻松地分配它们,如下所示。

double (*A)[n] = malloc(sizeof(double[n][n]));

and that's it. You can then easily use it as you are used for 2D arrays with something like A[i][j]. And don't forget that one at the end

就是这样。然后你就可以很容易地使用它,就像你在2D数组中使用类似[i][j]那样的东西。别忘了最后一个。

free(A);

Randy Meyers wrote series of articles explaining variable length arrays (VLAs).

兰迪·迈耶斯(Randy Meyers)写了一系列解释可变长数组(VLAs)的文章。

#3


49  

Basics

Arrays in c are declared and accessed using the [] operator. So that

使用[]操作符声明和访问c中的数组。这

int ary1[5];

declares an array of 5 integers. Elements are numbered from zero so ary1[0] is the first element, and ary1[4] is the last element. Note1: There is no default initialization, so the memory occupied by the array may initially contain anything. Note2: ary1[5] accesses memory in an undefined state (which may not even be accessible to you), so don't do it!

声明一个5个整数的数组。元素的编号为0,所以ary1[0]是第一个元素,而ary1[4]是最后一个元素。Note1:没有默认的初始化,因此数组所占用的内存最初可能包含任何内容。Note2: ary1[5]以未定义的状态访问内存(甚至可能无法访问),所以不要这样做!

Multi-dimensional arrays are implemented as an array of arrays (of arrays (of ... ) ). So

多维数组被实现为数组的数组(数组(…))。所以

float ary2[3][5];

declares an array of 3 one-dimensional arrays of 5 floating point numbers each. Now ary2[0][0] is the first element of the first array, ary2[0][4] is the last element of the first array, and ary2[2][4] is the last element of the last array. The '89 standard requires this data to be contiguous (sec. A8.6.2 on page 216 of my K&R 2nd. ed.) but seems to be agnostic on padding.

声明一个数组的3个一维数组的5个浮点数。现在ary2[0][0]是第一个数组的第一个元素,ary2[0][4]是第一个数组的最后一个元素,而ary2[2][4]是最后一个数组的最后一个元素。89标准要求这些数据是连续的(sec. A8.6.2,在我的K&R 2的第216页)。但在填充物上似乎是不可知论者。

Trying to go dynamic in more than one dimension

If you don't know the size of the array at compile time, you'll want to dynamically allocate the array. It is tempting to try

如果在编译时不知道数组的大小,则需要动态地分配数组。这是很诱人的尝试。

double *buf3;
buf3 = malloc(3*5*sizeof(double));
/* error checking goes here */

which should work if the compiler does not pad the allocation (stick extra space between the one-dimensional arrays). It might be safer to go with:

如果编译器没有对分配进行填充(在一维数组之间添加额外的空间),那么这应该起作用。这样做可能更安全:

double *buf4;
buf4 = malloc(sizeof(double[3][5]));
/* error checking */

but either way the trick comes at dereferencing time. You can't write buf[i][j] because buf has the wrong type. Nor can you use

但不管怎样,这个技巧都是在取消时间的时候出现的。你不能写buf[i][j],因为buf有错误的类型。你也不能使用

double **hdl4 = (double**)buf;
hdl4[2][3] = 0; /* Wrong! */

because the compiler expects hdl4 to be the address of an address of a double. Nor can you use double incomplete_ary4[][]; because this is an error;

因为编译器期望hdl4是双精度地址的地址。也不能使用double incomplete_ary4[][];因为这是一个错误;

So what can you do?

那么你能做什么呢?

  • Do the row and column arithmetic yourself
  • 你自己做行和列算术吗?
  • Allocate and do the work in a function
  • 在一个函数中分配和执行工作。
  • Use an array of pointers (the mechanism qrdl is talking about)
  • 使用一组指针(机制qrdl正在讨论)

Do the math yourself

Simply compute memory offset to each element like this:

简单地计算每个元素的内存偏移量:

  for (i=0; i<3; ++i){
     for(j=0; j<3; ++j){
        buf3[i * 5 + j] = someValue(i,j); /* Don't need to worry about 
                                             padding in this case */
     }
  }

Allocate and do the work in a function

Define a function that takes the needed size as an argument and proceed as normal

定义一个函数,它将所需的大小作为参数,并按照正常进行。

void dary(int x, int y){
  double ary4[x][y];
  ary4[2][3] = 5;
}

Of course, in this case ary4 is a local variable and you can not return it: all the work with the array must be done in the function you call of in functions that it calls.

当然,在本例中,ary4是一个局部变量,您不能返回它:所有与数组相关的工作都必须在函数调用的函数中完成。

An array of pointers

Consider this:

考虑一下:

double **hdl5 = malloc(3*sizeof(double*));
/* Error checking */
for (i=0; i<3; ++i){
   hdl5[i] = malloc(5*sizeof(double))
   /* Error checking */
}

Now hdl5 points to an array of pointers each of which points to an array of doubles. The cool bit is that you can use the two-dimensional array notation to access this structure---hdl5[0][2] gets the middle element of the first row---but this is none-the-less a different kind of object than a two-dimensional array declared by double ary[3][5];.

现在,hdl5指向一个指针数组,每个指针指向一个双打数组。很酷的一点是,你可以使用二维数组表示法来访问这个结构——-hdl5[0][2]得到第一行的中间元素——但这是一种不同的对象,而不是双ary[3][5]所声明的二维数组。

This structure is more flexible then a two dimensional array (because the rows need not be the same length), but accessing it will generally be slower and it requires more memory (you need a place to hold the intermediate pointers).

这个结构更灵活,然后是一个二维数组(因为行不需要相同的长度),但是访问它通常会比较慢,而且需要更多的内存(需要一个位置来保存中间指针)。

Note that since I haven't setup any guards you'll have to keep track of the size of all the arrays yourself.

请注意,由于我没有设置任何守卫,所以您必须自己跟踪所有数组的大小。

Arithmetic

c provides no support for vector, matrix or tensor math, you'll have to implement it yourself, or bring in a library.

c不支持向量、矩阵或张量数学,你必须自己实现它,或者引入一个库。

Multiplication by a scaler and addition and subtraction of arrays of the same rank are easy: just loop over the elements and perform the operation as you go. Inner products are similarly straight forward.

一个标量的乘法运算和加法和减法都很简单:只需对元素进行循环,然后执行操作。内部产品同样是直接的。

Outer products mean more loops.

外部产品意味着更多的循环。

#4


9  

If you know the number of columns at compile time, it's pretty simple:

如果您知道编译时的列数,很简单:

#define COLS ...
...
size_t rows;
// get number of rows
T (*ap)[COLS] = malloc(sizeof *ap * rows); // ap is a *pointer to an array* of T

You can treat ap like any 2D array:

你可以像对待任何2D数组一样对待ap:

ap[i][j] = x;

When you're done you deallocate it as

当你完成之后,你会把它重新分配。

free(ap);

If you don't know the number of columns at compile time, but you're working with a C99 compiler or a C2011 compiler that supports variable-length arrays, it's still pretty simple:

如果您不知道编译时的列数,但是您使用的是C99编译器或支持可变长度数组的C2011编译器,它仍然非常简单:

size_t rows;
size_t cols;
// get rows and cols
T (*ap)[cols] = malloc(sizeof *ap * rows);
...
ap[i][j] = x;
...
free(ap);

If you don't know the number of columns at compile time and you're working with a version of C that doesn't support variable-length arrays, then you'll need to do something different. If you need all of the elements to be allocated in a contiguous chunk (like a regular array), then you can allocate the memory as a 1D array, and compute a 1D offset:

如果您不知道编译时的列数,并且您正在使用一个不支持可变长度数组的C版本,那么您将需要做一些不同的事情。如果您需要将所有元素分配到一个连续的块中(像一个常规数组),那么您可以将内存分配为一维数组,并计算1D偏移量:

size_t rows, cols;
// get rows and columns
T *ap = malloc(sizeof *ap * rows * cols);
...
ap[i * rows + j] = x;
...
free(ap);

If you don't need the memory to be contiguous, you can follow a two-step allocation method:

如果您不需要内存是连续的,您可以采用两步分配方法:

size_t rows, cols;
// get rows and cols
T **ap = malloc(sizeof *ap * rows);
if (ap)
{
  size_t i = 0;
  for (i = 0; i < cols; i++)
  {
    ap[i] = malloc(sizeof *ap[i] * cols);
  }
}

ap[i][j] = x;

Since allocation was a two-step process, deallocation also needs to be a two-step process:

由于分配是两个步骤的过程,所以deallocation也需要一个两步的过程:

for (i = 0; i < cols; i++)
  free(ap[i]);
free(ap);

#5


0  

malloc will do.

malloc。

 int rows = 20;
 int cols = 20;
 int *array;

  array = malloc(rows * cols * sizeof(int));

Refer the below article for help:-

参考下面的文章寻求帮助:-。

http://courses.cs.vt.edu/~cs2704/spring00/mcquain/Notes/4up/Managing2DArrays.pdf

http://courses.cs.vt.edu/ cs2704 spring00 / / Managing2DArrays.pdf mcquain / Notes / 4

#6


-1  

There's no way to allocate the whole thing in one go. Instead, create an array of pointers, then, for each pointer, create the memory for it. For example:

没有办法一次性全部分配。相反,创建一个指针数组,然后,为每个指针创建内存。例如:

int** array;
array = (int**)malloc(sizeof(int*) * 50);
for(int i = 0; i < 50; i++)
    array[i] = (int*)malloc(sizeof(int) * 50);

Of course, you can also declare the array as int* array[50] and skip the first malloc, but the second set is needed in order to dynamically allocate the required storage.

当然,您也可以将数组声明为int* array[50],并跳过第一个malloc,但是为了动态地分配所需的存储,需要第二个设置。

It is possible to hack a way to allocate it in a single step, but it would require a custom lookup function, but writing that in such a way that it will always work can be annoying. An example could be L(arr,x,y,max_x) arr[(y)*(max_x) + (x)], then malloc a block of 50*50 ints or whatever and access using that L macro, e.g.

可以使用一种方法将其分配到单个步骤中,但是它需要一个定制的查找功能,但是以这样一种方式来编写它总是会很烦人。一个例子可以是L(arr,x,y,max_x) arr[(y)*(max_x) + (x)],然后是malloc (50*50 int),或者任何使用L宏的访问权限。

#define L(arr,x,y,max_x) arr[(y)*(max_x) + (x)]

int dim_x = 50;
int dim_y = 50;

int* array = malloc(dim_x*dim_y*sizeof(int));

int foo = L(array, 4, 6, dim_x);

But that's much nastier unless you know the effects of what you're doing with the preprocessor macro.

但是,除非您知道使用预处理器宏所做的工作的影响,否则会更糟糕。

#7


-1  

Here is working code that defines a subroutine make_3d_array to allocate a multidimensional 3D array with N1, N2 and N3 elements in each dimension, and then populates it with random numbers. You can use the notation A[i][j][k] to access its elements.

下面是定义子例程make_3d_array的工作代码,用于在每个维度中分配一个具有N1、N2和N3元素的多维3D数组,然后用随机数填充它。你可以用A[i][j][k]来访问它的元素。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


// Method to allocate a 2D array of floats
float*** make_3d_array(int nx, int ny, int nz) {
    float*** arr;
    int i,j;

    arr = (float ***) malloc(nx*sizeof(float**));

    for (i = 0; i < nx; i++) {
        arr[i] = (float **) malloc(ny*sizeof(float*));

        for(j = 0; j < ny; j++) {
            arr[i][j] = (float *) malloc(nz * sizeof(float));
        }
    }

    return arr;
} 



int main(int argc, char *argv[])
{
    int i, j, k;
    size_t N1=10,N2=20,N3=5;

    // allocates 3D array
    float ***ran = make_3d_array(N1, N2, N3);

    // initialize pseudo-random number generator
    srand(time(NULL)); 

    // populates the array with random numbers
    for (i = 0; i < N1; i++){
        for (j=0; j<N2; j++) {
            for (k=0; k<N3; k++) {
                ran[i][j][k] = ((float)rand()/(float)(RAND_MAX));
            }
        }
   }

    // prints values
    for (i=0; i<N1; i++) {
        for (j=0; j<N2; j++) {
            for (k=0; k<N3; k++) {
                printf("A[%d][%d][%d] = %f \n", i,j,k,ran[i][j][k]);
            }
        }
    }

    free(ran);
}

#8


-2  

int rows, columns;
/* initialize rows and columns to the desired value */

    arr = (int**)malloc(rows*sizeof(int*));
        for(i=0;i<rows;i++)
        {
            arr[i] = (int*)malloc(cols*sizeof(int));
        }

#9


-6  

Why, colleagues, nobody revealed the fact that no exact solution exists in the realm of C? but only in C++ (by exact I mean that above and other site's solutions differ from true C-multidimentional arrays with: aditional entities and so additional memory, etc).

为什么,同事们,没有人发现在C领域没有确切的解决方案?但只有在c++中(我的意思是,上面和其他站点的解决方案不同于真正的C-多维数组:传统实体和额外的内存等等)。

In C++ you must implement (just several lines of code):

在c++中,你必须实现(仅仅几行代码):

typedef double T;
class Matrix2D
{
public:
    Matrix2D(int, int);
   ~Matrix2D();
    T* operator[](int);
private:
    T* const  memory;
    const int rows;
    const int cols;
};

Matrix2D::Matrix2D(int r, int c) : rows(r), cols(c), memory(new T[r*c]) {}
Matrix2D::~Matrix2D() { delete[]  memory; }
T* Matrix2D::operator[](int row) {  return memory + cols*row;}

That's all for those who use code like this: a[i][j].

这都是为那些使用这样的代码的人所做的:a[i][j]。

But for exact similarity with C-multidimensional arrays that class (Matrix2D) lacks double-pointer arithmetics, to be used like this: (*(a+i))[j]. That is not difficult: implement inner clsss "doublePointer" with arithmetics and dereference operators. But I'd rather implemented sort of iterator for such purposes (to step from row to row).

但是,与c -多维数组的完全相似(Matrix2D)缺少双指针算术,可以这样使用:(*(a+i))[j]。这并不困难:用算术和引用运算符来实现内部clsss“doublePointer”。但是,为了达到这样的目的,我宁愿实现类似的迭代器(从行到行)。

More than 2 dimensions? You just need inner classes that implement corresponding operator[]...[] of (n-1)-dimension. Alas, routine..

二维多?您只需要实现相应操作符的内部类[]…[](n - 1)维度。唉,常规的. .