c语言 - 如何释放结构中的动态 2D 数组?



我在此结构内有一个动态的2D数组:

struct mystruct{
    int mySize;
    int **networkRep;
};

在我的代码块中,我使用它如下:

struct myStruct astruct[100];
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
// do stuff...
int i;
for(i=0; i<100; i++)
    freeMatrix(astruct[i].networkRep, 200);

这就是我声明2D数组的方式:

int** declareMatrix(int **mymatrix, int rows, int columns)
{
    mymatrix = (int**) malloc(rows*sizeof(int*));
    if (mymatrix==NULL)
        printf("Error allocating memory!n");
    int i,j;
    for (i = 0; i < rows; i++)
        mymatrix[i] = (int*) malloc(columns*sizeof(int));
    for(i=0; i<rows; i++){
        for(j=0; j<columns; j++){
            mymatrix[i][j] = 0;
        }
    }
    return mymatrix;
}

这就是我释放2D数组的方式:

void freeMatrix(int **matrix, int rows)
{
    int i;
    for (i = 0; i < rows; i++){
        free(matrix[i]);
    }
    free(matrix);
    matrix = NULL;
}

我看到的奇怪的behvior是,当我编译并运行程序时,一切看起来都还好。但是,当我将stdout送到txt文件时,我会遇到SEG错误。但是,如果我评论包含" freematrix"调用的循环,则不会发生SEG故障。我在做什么错?

我在免费代码中看不到任何问题,除了freeMatrix被要求使用100次,而您的分配只是1

所以,要么您分配如下:

 for(int i=0; i<100; i++) //Notice looping over 100 elements. 
    astruct[i].networkRep = declareMatrix(astruct[i].networkRep, 200, 200);

或仅适用于您在原始代码中分配的0个元素。

freeMatrix(astruct[0].networkRep, 200);

在Sidenote上:初始化您的astruct array

mystruct astruct[100] = {};
struct myStruct astruct[100];
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
// do stuff...
int i;
for(i=0; i<100; i++)
    freeMatrix(astruct[i].networkRep, 200);

您分配了一个ASCUCT,但免费100个;如果99个额外的额外的任何一个都不为空,那将崩溃,当您进行重定向时,这可能会发生。(由于Ascruct在堆栈上,它将包含那里留在那里的所有内容。)

其他问题:

您使用的是数字文字而不是明显常数...定义数字和numcols并始终如一地使用它们。

摆脱第一个dectarematrix的参数...您传递一个值,但永远不会使用它。

在freematrix中,

matrix = NULL;

什么也不做。通过优化开启,编译器甚至不会生成任何代码。

if (mymatrix==NULL)
    printf("Error allocating memory!n");

您应该在错误时退出(1),否则您的程序将崩溃,甚至可能不会看到错误消息,因为a)Stdout被缓冲,并且b)您将其重定向到文件。这也是将错误消息写给stderr而不是Stdout的原因。

astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200); 

您没有传递指针的地址。它只是将内存中的值传递到不符合不关键的函数。

和您唯一的初始化结构的第一个变量,但是当您试图释放内存时,您正在未分配内存(尚未分配)(astruct [1]等,依此类推,直到100)。

当您使用Malloc时,它实际上比您指定的要多得多。额外的内存用于存储信息,例如块的大小,以及指向下一个免费/二手块的链接,有时是一些 guard data ,可以帮助系统检测是否在过去的末尾写入分配的块。

如果您通过其他地址,它将访问包含垃圾的内存,因此其行为不确定(但最常导致崩溃)

索引并计数一个未签名的整数类型就足够了。size_t是这种选择的类型,因为它保证足够大,可以在目标计算机上的每个字节/数组的元素解决/索引。

struct mystruct
{
  size_t mySize;
  int ** networkRep;
};

始终正确初始化变量:

struct myStruct astruct[100] = {0};

分配器的几个问题:

  • 让它有机会返回特定的错误代码。这通常是通过使用返回的函数为so的函数来完成的。
  • 使用size_t进行计数器,指示和大小("行","列")(有关为什么请参见上文)。
  • 进行适当的错误检查。
  • 在工作期间发生错误时清理。
  • 请勿施放malloc()返回的值,因为在C中,不需要,不推荐
  • 使用perror()来记录错误,因为它从OS中获得最大的AS aS Possibe。

可以做到的:

int declareMatrix(int *** pmymatrix, size_t rows, size_t columns)
{
    int result = 0; /* Be optimistc. */
    assert(NULL != pmatrix);
    *pmymatrix = malloc(rows * sizeof(**pmymatrix));
    if (NULL == *pmymatrix)
    {
      perror("malloc() failed");
      result = -1;
      goto lblExit;
    }
    { 
      size_t i, j;
      for (i = 0; i < rows; i++)
      {
        (*pmymatrix)[i] = malloc(columns * sizeof(***pmymatrix));
        if (NULL ==   (*pmymatrix)[i])
        {
          perror("malloc() failed");
          freeMatrix(pmymatrix); /* Clean up. */
          result = -1;
          goto lblExit;
        }
        for(i = 0; i < rows; ++i)
        {
          for(j = 0; j < columns; ++j)
          {
            (*pmymatrix)[i][j] = 0;
          }
        }
      }
    }
lblExit:
    return 0;
}

De-Olocator的两个问题:

  • 马克(Mark
  • 在采取行动之前对输入进行验证。

可以做到的:

void freeMatrix(int *** pmatrix, size_t rows)
{
  if (NULL != pmatrix)
  {
    if (NULL != *pmatrix)
    {
      size_t i;
      for (i = 0; i < rows; ++i)
      {
        free((*pmatrix)[i]);
      }
    }
    free(*pmatrix);
    *pmatrix = NULL;
  }
}

然后使用这样的东西:

struct myStruct astruct[100] = {0};
...
int result = declareMatrix(&astruct[0].networkRep, 200, 200);
if (0 != result)
{
  fprintf("declareMatrix() failed.n");
}
else
{
// Note: Arriving here has only the 1st element of astruct initialised! */
// do stuff...
}
{
  size_t i;
  for(i = 0; i < 100; ++i)
  {
    freeMatrix(&astruct[i].networkRep, 200);
  }
}

相关内容

  • 没有找到相关文章

最新更新