在函数C中分配内存2d数组

时间:2022-09-06 12:09:55

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.

但它不工作。

upd: corrected function (quick answer)

upd:修正函数(快速回答)

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

8 个解决方案

#1


23  

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 []).

您的代码在*arr[i]=(int*)malloc(m*sizeof(int))处出错;因为[]运算符的优先级高于* deference运算符:在表达式*arr[i]中,首先计算arr[i],然后应用*。您需要的是相反的(取消引用arr,然后应用[])。

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

使用圆括号(*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));
} 

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:

另外,创建2D数组的更好方法是使用一个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
} 

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.

注意,在第二种技术中,malloc只被调用两次,因此在deallocation代码中,free只被调用两次,而不是在循环中调用。所以这项技术应该更好。

#2


3  

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.

如果你的数组不需要调整大小(你可以,但是il会有点复杂),有一种更简单/更有效的方法可以在C中构建2D数组。

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

看看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.

第二种方法(用于数组array2)非常简单,不那么痛苦(尝试为mallocs的返回值添加测试),而且方法更有效。

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

我刚刚对它进行了基准测试,为一个200x100的数组分配并分配了100000次:

  • Method 1 : 1.8s
  • 方法1:1.8 s
  • Method 2 : 47ms
  • 方法2:47女士

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).

而且数组中的数据将更加连续,这可能会加快速度(您可能会得到一些更有效的技术来复制、重置……)数组以这种方式分配)。

#3


2  

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

#4


2  

Rather allocating the memory in many different block, one can allocate this in a consecutive block of memory. Do the following:

与其将内存分配到许多不同的块中,不如将其分配到一个连续的内存块中。执行以下操作:

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

#5


1  

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

#6


0  

I have tried the following code for allocating memory to 2 dimensional array.

我尝试了下面的代码将内存分配到二维数组中。

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

Output of the above code is:-

以上代码的输出为:-。

1 2 3

1 2 3

4 5 6

4 5 6

7 8 9

7 8 9

In order to understand 2 dimensional array in terms of pointers, we need to understand how it will be allocated in memory, it should be something like this:-

为了在指针上理解二维数组,我们需要理解它是如何在内存中分配的,它应该是这样的:-。

                1    2    3
    1000 -->   100  104  108

                4    5    6
    1004 -->   200  204  208

                7    8    9
    1008 -->   300  304  308 

from the above, we understand that, when we allocate memory to pointer p which is a double pointer, it is pointing to an array of integers, so in this example, we see that the 0x1000 is pointer p.

从上面,我们知道,当我们将内存分配给指针p(一个双指针)时,它指向一个整数数组,所以在这个例子中,我们看到0x1000是指针p。

This pointer is pointing to integer pointer *p which is array of integers, when memory is allocated inside the inner for loop, during first iteration the pointer is 0x100 which is pointing to integer value 1, when we assign **p = j. Similarly it will be pointing to 2 and 3 in the next iterations in the loop.

这个指针是指向整型指针* p整数数组,当内存分配在内心的for循环,在第一次迭代是0 x100的指针指向整型值1,当我们把* * p = j。同样它会指向2和3中的下一个迭代循环。

Before the next iteration of the outer loop, double pointer is incremented, inside the next iteration, as is seen in this example the pointer is now at 0x1004 and is pointing to integer pointer which is an array of integers 4,5,6 and similarly for the next iterations in the loop.

在外循环的下一个迭代之前,在下一个迭代中,双指针被递增,就像在这个例子中看到的,指针现在在0x1004并且指向一个整数指针,它是一个整数数组4,5,6,对于循环中的下一个迭代也是如此。

#7


0  

2d Array dynamically array using malloc:

使用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;

#8


-1  

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

#1


23  

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 []).

您的代码在*arr[i]=(int*)malloc(m*sizeof(int))处出错;因为[]运算符的优先级高于* deference运算符:在表达式*arr[i]中,首先计算arr[i],然后应用*。您需要的是相反的(取消引用arr,然后应用[])。

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

使用圆括号(*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));
} 

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:

另外,创建2D数组的更好方法是使用一个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
} 

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.

注意,在第二种技术中,malloc只被调用两次,因此在deallocation代码中,free只被调用两次,而不是在循环中调用。所以这项技术应该更好。

#2


3  

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.

如果你的数组不需要调整大小(你可以,但是il会有点复杂),有一种更简单/更有效的方法可以在C中构建2D数组。

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

看看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.

第二种方法(用于数组array2)非常简单,不那么痛苦(尝试为mallocs的返回值添加测试),而且方法更有效。

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

我刚刚对它进行了基准测试,为一个200x100的数组分配并分配了100000次:

  • Method 1 : 1.8s
  • 方法1:1.8 s
  • Method 2 : 47ms
  • 方法2:47女士

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).

而且数组中的数据将更加连续,这可能会加快速度(您可能会得到一些更有效的技术来复制、重置……)数组以这种方式分配)。

#3


2  

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

#4


2  

Rather allocating the memory in many different block, one can allocate this in a consecutive block of memory. Do the following:

与其将内存分配到许多不同的块中,不如将其分配到一个连续的内存块中。执行以下操作:

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

#5


1  

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

#6


0  

I have tried the following code for allocating memory to 2 dimensional array.

我尝试了下面的代码将内存分配到二维数组中。

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

Output of the above code is:-

以上代码的输出为:-。

1 2 3

1 2 3

4 5 6

4 5 6

7 8 9

7 8 9

In order to understand 2 dimensional array in terms of pointers, we need to understand how it will be allocated in memory, it should be something like this:-

为了在指针上理解二维数组,我们需要理解它是如何在内存中分配的,它应该是这样的:-。

                1    2    3
    1000 -->   100  104  108

                4    5    6
    1004 -->   200  204  208

                7    8    9
    1008 -->   300  304  308 

from the above, we understand that, when we allocate memory to pointer p which is a double pointer, it is pointing to an array of integers, so in this example, we see that the 0x1000 is pointer p.

从上面,我们知道,当我们将内存分配给指针p(一个双指针)时,它指向一个整数数组,所以在这个例子中,我们看到0x1000是指针p。

This pointer is pointing to integer pointer *p which is array of integers, when memory is allocated inside the inner for loop, during first iteration the pointer is 0x100 which is pointing to integer value 1, when we assign **p = j. Similarly it will be pointing to 2 and 3 in the next iterations in the loop.

这个指针是指向整型指针* p整数数组,当内存分配在内心的for循环,在第一次迭代是0 x100的指针指向整型值1,当我们把* * p = j。同样它会指向2和3中的下一个迭代循环。

Before the next iteration of the outer loop, double pointer is incremented, inside the next iteration, as is seen in this example the pointer is now at 0x1004 and is pointing to integer pointer which is an array of integers 4,5,6 and similarly for the next iterations in the loop.

在外循环的下一个迭代之前,在下一个迭代中,双指针被递增,就像在这个例子中看到的,指针现在在0x1004并且指向一个整数指针,它是一个整数数组4,5,6,对于循环中的下一个迭代也是如此。

#7


0  

2d Array dynamically array using malloc:

使用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;

#8


-1  

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