Allocate memory 2d array in function C

2019-01-01 07:03发布

How to allocate dynamic memory for 2d array in function ? I tried this way:

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

But it doesn't work.

8条回答
残风、尘缘若梦
2楼-- · 2019-01-01 07:44

Your code is wrong at *arr[i]=(int*)malloc(m*sizeof(int)); because the precedence of the [] operator is higher than the * deference operator: In the expression *arr[i], first arr[i] is evaluated then * is applied. What you need is the reverse (dereference arr, then apply []).

Use parentheses like this: (*arr)[i] to override operator precedence. Now, your code should look like this:

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

To understand further what happens in the above code, read this answer.

It is important that you always deallocate dynamically allocated memory explicitly once you are done working with it. To free the memory allocated by the above function, you should do this:

void deallocate_mem(int*** arr, int n){
    for (int i = 0; i < n; i++)
        free((*arr)[i]);
    free(*arr); 
}

Additionally, a better way to create a 2D array is to allocate contiguous memory with a single malloc() function call as below:

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
} 

To deallocate this memory:

void deallocate_mem(int*** arr, int* arr_data){
    free(arr_data);
    free(*arr);
}

Notice that in the second technique malloc is called only two times, and so in the deallocation code free is called only two times instead of calling it in a loop. So this technique should be better.

查看更多
无色无味的生活
3楼-- · 2019-01-01 07:47

Try the following code:

 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));
} 
查看更多
时光乱了年华
4楼-- · 2019-01-01 07:51

Consider this: Just single allocation

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

To Free:

free(a);
查看更多
无与为乐者.
5楼-- · 2019-01-01 07:53

If your array does not need to be resized (well, you can, but il will be a bit more complicated), there is an easier/more efficient way to build 2D arrays in C.

Take a look at http://c-faq.com/aryptr/dynmuldimary.html.

The second method (for the array called array2) is quite simple, less painful (try to add the tests for mallocs' return value), and way more efficient.

I've just benchmarked it, for a 200x100 array, allocated and deallocated 100000 times:

  • Method 1 : 1.8s
  • Method 2 : 47ms

And the data in the array will be more contiguous, which may speed things up (you may get some more efficient techniques to copy, reset... an array allocated this way).

查看更多
素衣白纱
6楼-- · 2019-01-01 07:54

2d Array dynamically array using malloc:

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;
查看更多
临风纵饮
7楼-- · 2019-01-01 07:57

That is an unnecessarily complicated way of allocating space for an array. Consider this:

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;
}
查看更多
登录 后发表回答