为2d数组c分配内存
我已经阅读了很多关于分配内存的帖子,我认为我理解这个概念,但是我被告知我必须使用一种类似这样的方法:为2d数组c分配内存,c,arrays,malloc,C,Arrays,Malloc,我已经阅读了很多关于分配内存的帖子,我认为我理解这个概念,但是我被告知我必须使用一种类似这样的方法: double ** malloc_array2d(size_t m, size_t n) { double **A; size_t i; A = malloc(m * sizeof(double *)); if (A == NULL) return NULL; A[0] = (double *) malloc(m * n *
double ** malloc_array2d(size_t m, size_t n)
{
double **A;
size_t i;
A = malloc(m * sizeof(double *));
if (A == NULL)
return NULL;
A[0] = (double *) malloc(m * n * sizeof(double));
if (A[0] == NULL)
{
free(A);
return NULL;
}
for (i = 1 ; i < m ; i++)
A[i] = A[0] + i *n;
return A;
}
double**malloc\u array2d(大小为m,大小为n)
{
双**A;
尺寸i;
A=malloc(m*sizeof(double*);
如果(A==NULL)
返回NULL;
A[0]=(双*)malloc(m*n*sizeof(双));
如果(A[0]==NULL)
{
免费(A);
返回NULL;
}
对于(i=1;i
当然,稍后我将不得不释放内存-但我不太理解这种方法,更具体地说,我无法看到在最后一行剩余指针被设置到内存块中时发生了什么(有人告诉过我。我不确定分配完后如何在矩阵/数组中插入元素。必须使poitners指针的每个指针指向有效的
malloc()
ed数据
for (int i = 0 ; i < n ; ++i)
A[i] = (double *) malloc(m * sizeof(double));
for(int i=0;i
您也可以一次将其全部分配,但是表示法A[i][j]
将不起作用
double ** malloc_array2d(size_t m, size_t n){
double **A;
size_t i;
A = malloc(m*sizeof(double *));
if (A == NULL) return NULL;
A[0]=(double *)malloc(m*n*sizeof(double));
if ( A[0] == NULL) {free(A); return NULL;}
for(i=1; i<m; i++) A[i]=A[0]+i*n;
return A;
}
此行为m个双指针分配空间
A[0] = (double *) malloc(m*n*sizeof(double));
[0]现在是m*n倍的内存块,这是2d阵列所需的全部倍
for (int i = 1; i < m; i++) {A[i] = A[0] + i * n;}
(inti=1;iA[0]+i*j+j
。这比访问指向双*B的A[i]并找到B[j]要快得多
内存管理是一个很难理解的话题,它需要一些时间。希望这会更有意义,并且我希望我没有让您更加困惑:)对于这种分配形式,您可以从将指针数组分配给其他数组开始,如下所示:
T **a = malloc( sizeof *a * N ); // N is the number of rows
sizeof*a
相当于sizeof(T*)
;数组中的每个元素都将是指向T
的指针。完成后,内存中会有如下内容:
+---+
a: | | a[0]
+---+
| | a[1]
+---+
| | a[2]
+---+
...
+---+
| | a[N-1]
+---+
+---+ +---------+---------+ +-----------+
a: | | a[0] ---> | a[0][0] | a[0][1] |...| a[0][M-1] |
+---+ +---------+---------+ +-----------+
| | a[1] ---> | a[1][0] | a[1][1] |...| a[1][M-1] |
+---+ +---------+---------+ +-----------+
| | a[2] ---> | a[2][0] | a[2][1] |...| a[2][M-1] |
+---+ +---------+---------+ +-----------+
...
+---+ +-----------+-----------+ +-------------+
| | a[N-1]--> | a[N-1][0] | a[N-1][1] |...| a[N-1][M-1] |
+---+ +-----------+-----------+ +-------------+
现在,对于这些元素中的每一个,我们分配另一块内存来保存T
类型的每个元素:
a[i] = malloc( sizeof *a[i] * M ); // M is the number of columns
每个a[i]
都有类型T*
,因此sizeof*a[i]
相当于sizeof(T)
完成后,我们的内存中会出现如下内容:
+---+
a: | | a[0]
+---+
| | a[1]
+---+
| | a[2]
+---+
...
+---+
| | a[N-1]
+---+
+---+ +---------+---------+ +-----------+
a: | | a[0] ---> | a[0][0] | a[0][1] |...| a[0][M-1] |
+---+ +---------+---------+ +-----------+
| | a[1] ---> | a[1][0] | a[1][1] |...| a[1][M-1] |
+---+ +---------+---------+ +-----------+
| | a[2] ---> | a[2][0] | a[2][1] |...| a[2][M-1] |
+---+ +---------+---------+ +-----------+
...
+---+ +-----------+-----------+ +-------------+
| | a[N-1]--> | a[N-1][0] | a[N-1][1] |...| a[N-1][M-1] |
+---+ +-----------+-----------+ +-------------+
因此,基本上您在这里所做的是分配N
分离T
的M
-元素数组,然后在T*
的N
-元素数组中收集指向这些数组的指针
您可以像任何普通的2D数组一样,以a[i][j]
的形式访问每个元素;记住表达式a[i][/code>被定义为*(a+i)
;我们从a
中的地址偏移i
元素(不是字节!),然后取消对结果的引用。因此a[i][j]
被计算为*(*(a+i)+j)
因此,在这种分配形式中需要记住几点:
数组的“行”在内存中不会是连续的;a[i][M-1]
后面的内存对象(很可能)不会是a[i+1][0]
由于每个“行”a[i]
都分配了对malloc
的调用,因此在解除分配a
之前,还必须显式地解除分配给free
(始终以与malloc
相反的顺序解除分配free
)
尽管我们可以将a
视为2D数组,但它没有数组类型,因此您无法使用sizeof a
技巧确定数组的大小;您只能获得指针类型的大小,而不是数组的总大小。因此,您需要自己跟踪数组大小
你可以随时用谷歌搜索。你也可以保持一致,你第二次抛出malloc()
时根本不要这样做,或者即使是丑陋的、不必要的,也要这样做,但要保持一致。对于,循环非常小,试着取一些具体的小值(比如m=n=2
)写下函数的作用,扩展循环迭代。为分配的块和指针绘制框和箭头…如果你仍然看不到发生了什么,请解释你理解的位。这不是一个2D数组,而是一个奇怪的数组模拟。这属于博物馆,现代C可以比C99做得更好。只需使用double(*arr)[m]=malloc(sizeof(double[n][m]));
一次分配一个2D数组。你甚至不需要一个特殊的函数。问题中的代码确实有效。它一次分配所有数组,然后将指针放入分配的块中。是的,我想这是我在谷歌搜索时看到的最常见的方法——这在我的头脑中是有意义的——但我刚刚被告知这是最简单的方法“天真”的方法,一个更快的方法是分配一个大内存块m*n,然后设置指针到这个内存块中——我的书说这样做:)谢谢!这完全有道理:)