如何在功能中为2d数组分配动态内存? 我试过这种方式:
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));
}
但它没有用。
答案 0 :(得分:25)
*arr[i]=(int*)malloc(m*sizeof(int));
您的代码错误,因为[]
运算符的precedence高于*
deference运算符:在表达式*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));
}
要进一步了解上述代码中发生的情况,请阅读this answer。
重要的是,一旦完成动态分配的内存,请务必明确释放动态分配的内存。要释放上述函数分配的内存,您应该这样做:
void deallocate_mem(int*** arr, int n){
for (int i = 0; i < n; i++)
free((*arr)[i]);
free(*arr);
}
此外,创建2D数组的更好方法是使用malloc()
函数调用allocate contiguous memory,如下所示:
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只被调用两次而不是在循环中调用它。所以这种技术应该更好。
答案 1 :(得分:3)
如果你的阵列不需要调整大小(好吧,你可以,但是会有点复杂),有一种更容易/更有效的方法来用C构建2D数组。
看看http://c-faq.com/aryptr/dynmuldimary.html。
第二种方法(对于名为array2的数组)非常简单,不那么痛苦(尝试为mallocs的返回值添加测试),并且效率更高。
我刚刚对它进行了基准测试,对于200x100阵列,分配和释放了100000次:
并且数组中的数据将更加连续,这可能会加快速度(您可能会获得一些更有效的技术来复制,重置......以这种方式分配的数组)。
答案 2 :(得分:2)
考虑一下:只需单一分配
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);
答案 3 :(得分:1)
这是为阵列分配空间的一种不必要的复杂方式。考虑一下:
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;
}
答案 4 :(得分:0)
我已尝试使用以下代码将内存分配给二维数组。
#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
为了从指针的角度理解二维数组,我们需要了解它将如何在内存中分配,它应该是这样的: -
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,它是整数数组,当内部for循环内部分配内存时,在第一次迭代期间指针为0x100,指向整数值1,当我们指定** p =学家类似地,它将在循环的下一次迭代中指向2和3。
在外循环的下一次迭代之前,双指针在下一次迭代中递增,如本示例所示,指针现在位于0x1004并指向整数指针,整数指针是整数数组4,5, 6并且类似地用于循环中的下一次迭代。
答案 5 :(得分:-1)
请尝试以下代码:
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));
}
答案 6 :(得分:-1)
使用malloc的2d Array动态数组:
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;