【问题标题】:How to free a two dimensional array allocated memory using int ** ptr如何使用 int ** ptr 释放二维数组分配的内存
【发布时间】:2015-07-09 03:15:08
【问题描述】:

如何使用使用 int ** ptr 分配内存的函数释放二维数组?

例如我使用allocArray( &ptrArray, row, column); 来分配数组。 使用此函数释放分配的内存的正确过程是什么: void freeArray( int *** pA, int row, int column)

#include <stdio.h>
#include <stdlib.h>

void allocArray( int *** pA, int row, int column)
{
    int i, j, count;

    *pA = (int **) malloc(row * sizeof(int *));
    for (int i =0; i<row; ++i)
    {
        (*pA)[i] = (int *) malloc( column * sizeof(int));
    }
    // Note that pA[i][j] is same as *(*(pA+i)+j)
    count = 0;
    for (i = 0; i <  row ; i++)
        for (j = 0; j < column; j++)
            (*pA)[i][j] = ++count;  // OR *(*(pA+i)+j) = ++count

    for (i = 0; i <  row; i++)  {
        for (j = 0; j < column; j++)  {
            printf("%d ", (*pA)[i][j]);
        }
        printf("\n");
    }
}

// How to free a two dimensional array  allocated memory using int ** ptr?
void freeArray( int *** pA, int row, int column)
{

}

void test_array_allocation()
{
    int i, j;
    int row = 3, column = 4;
    int ** ptrArray;

    allocArray( &ptrArray, row, column);

    printf("test_array_allocation\n");
    for (i = 0; i <  row; i++)  {
        for (j = 0; j < column; j++)  {
            printf("%d ", (ptrArray)[i][j]);
        }
        printf("\n");
    }
    freeArray(&ptrArray, row, column); // free allocated memory  
}

int main(int argc, const char * argv[]) {
    test_array_allocation();  
    return 0;
}

【问题讨论】:

  • 基本相同,但顺序相反:首先,释放每个(*pA)[i],然后释放*pA。你可能想重新设计你的代码。当int *** 之类的东西开始出现时,这很少是一个好兆头。
  • 如果你这样做,你能告诉我你会怎么做吗?
  • 最好使用函数原型:'void * allocArray(int nodeLength, int numRow, int numCol) 函数内部:void * theArray = NULL;然后分配行指针并将它们全部清除为NULL。然后,分配每一行的列。最好是单独初始化行列的初始化,而不是作为数组分配的一部分。
  • 在 C 中调用 malloc()(和函数族)1) 时,不要转换返回值。 2) 始终检查 (!=NULL) 返回值以确保操作成功。
  • 为行指针调用 malloc 的初始结果应该将结果分配的内存设置为 NULL。那么如果出现任何问题,释放内存将是一个简单的循环(将 NULL 传递给 free() 就可以了)

标签: c arrays memory free pointers


【解决方案1】:

如果你这样做,你能告诉我你会怎么做吗?

这就是我将如何实现它。我以前从未在 C 中实现过 2d 数组,写的代码很有趣。

#include <stdio.h>
#include <stdlib.h>

void*
xmalloc(size_t n)
{
  void* p = malloc(n);
  if (p == NULL)
    {
      printf("I handle my errors!\n");
      exit(EXIT_FAILURE);
    }
  return p;
}

int**
alloc2dArray(unsigned rows, unsigned cols)
{
  int** r = xmalloc(sizeof(int*) * rows);
  for (int i = 0; i < rows; i++)
    r[i] = xmalloc(sizeof(int) * cols);
  return r;
}

void
print2dArray(int** a, unsigned rows, unsigned cols)
{
  for (int i = 0; i < rows; i++) 
    {
      for (int j = 0; j < cols; j++)
      printf("%4d", a[i][j]);
      putchar('\n');
    }
}

void
free2dArray(int** x, unsigned rows)
{
  for (int i = 0; i < rows; i++)
    free(x[i]);
  free(x);
}

int main(void)
{
  int** x = alloc2dArray(10, 14);

  for (int i = 0; i < 10; i++)
    for (int j = 0; j < 14; j++)
      x[i][j] = i*j;

  print2dArray(x, 10, 14);
  free2dArray(x, 10);

  return 0;
}

另一个您可能不知道的提示:您可以在 GNU/Linux 上使用 valgrind 来验证您是否正确解除分配:

==9322== HEAP SUMMARY:
==9322==     in use at exit: 0 bytes in 0 blocks
==9322==   total heap usage: 11 allocs, 11 frees, 640 bytes allocated
==9322== 
==9322== All heap blocks were freed -- no leaks are possible
==9322== 
==9322== For counts of detected and suppressed errors, rerun with: -v
==9322== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

【讨论】:

  • 感谢 wrtmu,你真是个专业人士!
  • 感谢使用 valgrind 的提示!
【解决方案2】:

对于这个功能:

void freeArray( int *** pA, int row, int column)
{

}

不需要参数'column'。

void freeArray( int **pA, int row )
{
    for( int i = 0; i < row; i++ )
    {
        free( pA[i] );
    }
    free( pA );
}

【讨论】:

    【解决方案3】:

    对于malloc 的每次调用,都必须有对free 的相应调用。对free 的调用必须使用与对malloc 的相应调用返回的相同指针值。

    在您的情况下,您有以下几行使用malloc 分配内存。

    *pA = (int **) malloc(row * sizeof(int *));
    for (int i =0; i<row; ++i)
    {
        (*pA)[i] = (int *) malloc( column * sizeof(int));
    }
    

    必须有row 调用free 的次数,使用存储在(*pA) 中的值。

    然后,必须使用*pA 调用free

    现在,您可以将freeArray 实现为:

    // No need for using int ***. You are not going to modify pA
    // You are just going to use the pointer.
    // You don't need column in this function.
    
    void freeArray( int ** pA, int row)
    {
        for (int i =0; i<row; ++i)
        {
            free(pA[i]);
        }
        free(pA);
    }
    

    然后从test_array_allocation 调用它:

    freeArray(pA, row);
    

    【讨论】:

    • @AlterMann,他需要row,而不是columncolumn 仅用于确定在调用malloc 时使用的大小。对malloc 的调用只有row。因此,对free 的调用次数为row
    • 感谢 R Sahu!,你是一个了不起的专业人士!
    猜你喜欢
    • 1970-01-01
    • 2016-03-15
    • 2011-11-05
    • 2021-03-05
    • 2018-10-05
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多