Felipe
Felipe

Reputation: 35

What is the correct way to allocate this nested structures?

I'm having some trouble trying to figure out how to allocate and free the memory for this structures.

I need to use this to create FiniteTable's to use in Newton Interpolation.

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

The fist one is kind of a Node that has the real value.

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

FiniteTableRow keeps an array of FiniteTableValues.

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

FiniteTable then keeps an array of FiniteTableRows.

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

FiniteTableList is the list of FiniteTable's

I tried to debugg it with valgrind and it seems I always access some address that I didn't allocate.

Also, is this the right way to deallocate all ?

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

Upvotes: 0

Views: 97

Answers (1)

Kyrill
Kyrill

Reputation: 3811

In your deallocation example the Ftl object is a FiniteTableList rather than a pointer (FiniteTableList *). I think you meant to write:

FiniteTableList ftl ...

To allocate memory for a FiniteTableList structure you'd do something like this:

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

If you want to zero-initialise the memory you allocate you can substitute the calls to malloc by calloc

Upvotes: 1

Related Questions