在函数C中分配内存2d数组
如何为函数中的2d数组分配dynamic内存? 我试过这种方式:
int main() { int m=4,n=3; int** arr; allocate_mem(&arr,n,m); } void allocate_mem(int*** arr,int n, int m) { *arr=(int**)malloc(n*sizeof(int*)); for(int i=0;i<n;i++) *arr[i]=(int*)malloc(m*sizeof(int)); }
但它不起作用。 有人可以纠正我的错误?
更新:更正的function(快速回答)
void allocate_mem(int*** arr, int n, int m) { *arr = (int**)malloc(n*sizeof(int*)); for(int i=0; i<n; i++) (*arr)[i] = (int*)malloc(m*sizeof(int)); }
你的代码在*arr[i]=(int*)malloc(m*sizeof(int));
因为[]
运算符的优先级高于*
deference运算符:在expression式*arr[i]
,首先计算arr[i]
,然后应用*
。 你需要的是反向(取消引用arr
,然后应用[]
)。
使用这样的括号: (*arr)[i]
覆盖运算符优先级。 现在,你的代码应该是这样的:
void allocate_mem(int*** arr, int n, int m) { *arr = (int**)malloc(n*sizeof(int*)); for(int i=0; i<n; i++) (*arr)[i] = (int*)malloc(m*sizeof(int)); }
要进一步了解上述代码中发生了什么,请阅读此答案 。
一旦完成了dynamic分配的内存,一定要明确地释放它,这一点非常重要。 为了释放上述函数分配的内存,你应该这样做:
void deallocate_mem(int*** arr, int n){ for (int i = 0; i < n; i++) free((*arr)[i]); free(*arr); }
此外,创build二维数组的更好方法是使用一个malloc()
函数调用来分配连续内存 ,如下所示:
int* allocate_mem(int*** arr, int n, int m) { *arr = (int**)malloc(n * sizeof(int*)); int *arr_data = malloc( n * m * sizeof(int)); for(int i=0; i<n; i++) (*arr)[i] = arr_data + i * m ; return arr_data; //free point }
释放这个内存:
void deallocate_mem(int*** arr, int* arr_data){ free(arr_data); free(*arr); }
请注意,在第二种技术中,malloc仅被调用两次,因此在释放代码中free只被调用两次,而不是在一个循环中调用它。 所以这个技巧应该会更好。
如果你的数组不需要resize(当然,你可以,但是会更复杂一点),在C中构build二维数组有一个更简单/更有效的方法。
看看http://c-faq.com/aryptr/dynmuldimary.html 。
第二种方法(对于名为array2的数组)非常简单,不那么痛苦(尝试为mallocs的返回值添加testing),并且更高效。
我只是对它进行了基准testing,对于一个200×100的arrays,分配和释放了10万次:
- 方法1:1.8s
- 方法2:47ms
而数组中的数据将更加连续,这可能会加快速度(您可能会得到一些更有效的技术来复制,重置…这样分配的数组)。
考虑这个:只是单一的分配
int** allocate2D(int m, int n) { int **a = (int **)malloc(m * sizeof(int *) + (m * n * sizeof(int))); int *mem = (int *)(a + m); for(int i = 0; i < m; i++) { a[i] = mem + (i * n); } return a; }
释放:
free(a);
在许多不同的块中分配内存,可以在连续的内存块中分配这个内存。 执行以下操作:
int** my2DAllocation(int rows,int columns) { int i; int header= rows *sizeof(int *); int data=rows*cols*sizeof(int); int ** rowptr=(int **)malloc(header+data); if(rowptr==NULL) { return NULL: } int * buf=(int*)(rowptr+rows); for(i=0;i<rows;i++) { rowptr[i]=buf+i*cols; } return rowptr; }
这是为数组分配空间不必要的复杂方式。 考虑这个:
int main(void) { size_t m = 4, n = 3; int (*2D_array)[m]; 2D_array = malloc(n * sizeof *2D_array); free(2D_array); return 0; }
我已经尝试了以下代码分配内存到2维数组。
#include<stdio.h> #include<malloc.h> void main(void) { int **p;//double pointer holding a 2d array int i,j; for(i=0;i<3;i++) { p=(int**)(malloc(sizeof(int*)));//memory allocation for double pointer for(j=(3*i+1);j<(3*i+4);j++) { *p = (int*)(malloc(sizeof(int)));//memory allocation for pointer holding integer array **p = j; printf(" %d",**p);//print integers in a row printf("\n"); p++; } } }
上述代码的输出是: –
1 2 3
4 5 6
7 8 9
为了从指针的angular度理解二维数组,我们需要了解它将如何在内存中分配,它应该是这样的:
1 2 3 1000 --> 100 104 108 4 5 6 1004 --> 200 204 208 7 8 9 1008 --> 300 304 308
从上面我们知道,当我们将内存分配给一个双指针指针p时,它指向一个整数数组,所以在这个例子中,我们看到0x1000是指针p。
当指针指向** p = j时,这个指针指向整数指针* p,这是整数数组,当内部for循环内部分配内存时,第一次迭代期间指针是0x100,指向整数值1。 同样的,它会在循环的下一个迭代中指向2和3。
在外循环的下一次迭代之前,双指针递增,在下一次迭代中增加,正如在这个例子中看到的那样,指针现在在0x1004,指向整数指针,它是一个整数4,5,6的数组,并且类似为循环中的下一个迭代。
2d使用mallocdynamic数组的数组:
int row = 4; int column = 4; int val = 2; // memory allocation using malloc int **arrM = (int**)malloc (row*sizeof(int*)); for (int i=0;i<row;i++) { arrM[i] = (int*)malloc(column*sizeof(int)); // insert the value for each field for (int j =0;j<column;j++,val++) { arrM[i][j] = val; } } // De-allocation for (int i=0;i<row;i++) { free(arrM[i]); } free(arrM); arrM = 0; // // Now using New operator: // int **arr = new int*[row]; int k = 1; for (int i=0;i<row;i++) { arr[i] = new int[column]; // insert the value for each field for (int j =0;j<column;j++,k++) { arr[i][j] = k; } } cout<<"array value is = "<<*(*(arr+0)+0)<<endl; cout<<"array value is = "<<*(*(arr+3)+2)<<endl; // Need to deallcate memory; for (int i=0;i<row;i++) { delete [] arr[i]; } delete []arr; arr = 0;
试试下面的代码:
void allocate_mem(int*** arr,int n, int m) { *arr=(int**)malloc(n*sizeof(int*)); for(int i=0;i<n;i++) *(arr+i)=(int*)malloc(m*sizeof(int)); }