【问题标题】:What is the correct way to allocate this nested structures?分配这种嵌套结构的正确方法是什么?
【发布时间】:2017-11-11 19:02:25
【问题描述】:

我在试图弄清楚如何为这些结构分配和释放内存时遇到了一些麻烦。

我需要用它来创建在牛顿插值中使用的 FiniteTable。

typedef struct{
  unsigned int empty;
  float value;
}FiniteTableValue;

第一个是具有实际价值的节点。

typedef struct{
  FiniteTableValue *column;
  unsigned int length;
}FiniteTableRow;

FiniteTableRow 保存一个 FiniteTableValues 数组。

typedef struct{
  FiniteTableRow *row;
  unsigned int length;
}FiniteTable;

FiniteTable 然后保留一个 FiniteTableRows 数组。

typedef struct{
  FiniteTable *tables;
  unsigned int length;
}FiniteTableList;

FiniteTableList 是 FiniteTable 的列表

我尝试使用 valgrind 对其进行调试,但似乎我总是访问一些我没有分配的地址。

另外,这是解除所有分配的正确方法吗?

FiniteTableList *ftl ...
  ...
  for(int i = 0; i < ftl->length; i++){
    FiniteTable table = ftl->tables[i];
    for(int j = 0; j < table.length; j++){
      FiniteTableRow row = table.row[j];
      free(row.column);
    }
    free(table.row);
  }
  free(ftl->tables);
  free(ftl);

【问题讨论】:

  • 什么是 valgrind 错误?如果涉及未定义的数据,请尝试使用 --track-origins=yes 运行。
  • 它用于“条件跳转或移动取决于未初始化的值”我有点知道它们在哪里,但我只需要知道如何简单地使用 malloc 启动所有这些结构
  • 在这种情况下,--track-origins=yes 应该指向您需要修复的源代码位置。如果没有,则需要发布 valgrind 错误和相应的源代码。
  • @TomKarzes 哦,这里是错字。上的代码是正确的。

标签: c memory malloc structure


【解决方案1】:

在您的释放示例中,Ftl 对象是 FiniteTableList 而不是指针 (FiniteTableList *)。我想你的意思是写:

FiniteTableList ftl ...

要为FiniteTableList 结构分配内存,您需要执行以下操作:

/* Assuming every table in the list will have num_rows rows and num_columns columns.  */
FiniteTableList *
allocate_table_list (int num_rows, num_columns, int num_tables)
{
  FiniteTableList * res = malloc (sizeof *res);
  res->tables = malloc (num_tables * sizeof (*res->tables));
  res->length = num_tables;
  for (int t = 0; t < num_tables; t++)
    {
      FiniteTable table = res->tables[t];
      table.row = malloc (num_rows * sizeof (*table.row));
      table.length = num_rows;
      for (int r = 0; r < num_rows; r++)
        {
          FiniteTableRow row = table.row[r];
          row.column = malloc (num_columns * sizeof (*row.column));
          row.length = num_columns;
        }
    }
  return res;
}

如果你想对你分配的内存进行零初始化,你可以用calloc代替对malloc的调用

【讨论】:

  • 你在做 FiniteTableList * res = malloc(sizeof *res); 时分配了什么?
  • 您正在为顶级 FiniteTableList 对象分配内存。 (sizeof *res) 表达式的意思是“指针 res 指向的类型的大小”
猜你喜欢
  • 1970-01-01
  • 2017-03-04
  • 2019-08-08
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多