简体   繁体   中英

malloc nested variable array of structs?

How do you go about allocating the data for a struct like below properly (tried adding comments for clarity but been up far too many hours so apologies if they make little to no sense)?

struct Cell
{
    int *iData;
    char *cData;
};

struct Row
{
    struct Cell *row;
};

struct Grid
{
    struct Row *grid;
    // Where maxData would be user defined
    // would be the number of elements allocated to member variables of cell
    int maxData;
    // struct Row with rowSize = 3 would be like below?
    // [*Cell][cell][cell][cell]
    int rowSize;
    // columnSize & rowSize = 3 would look something like below?
    //[*Row][*Cell][cell][cell][cell]
    //[*Row][*Cell][cell][cell][cell]
    //[*Row][*Cell][cell][cell][cell]
    int columnSize;
};



//somewhere else in program 
struct Grid *g = malloc(sizeof(struct Grid));
//make user maxData rowSize columnSize assignments here
for(int i = 0; i < g->columnSize; i++)
{
    g->grid[i] = malloc(sizeof(struct Row));
    for(int j = 0; i < g->rowSize; j++)
    {
        g->grid[i]->row[j] = malloc(sizeof(struct Cell));
        g->grid[i]->row[j]->iData = malloc((sizeof(int)) * g->maxData);
        g->grid[i]->row[j]->cData = malloc((sizeof(char)) * g->maxData);
    }
}



Is my logic for memory allocation right here?

Was trying something similar in a database program im playing around with but, it segfaults and i cant tell if its my understanding of nested structs like this that is failing or i've just been a bit of a spanner somewhere else in that code.

Many thanks in advance

edit:

The struct that im actually trying to understand how to allocate for is below, just made an example so someone didn't solve my problem for me :) :

struct Address {
    int id;
    int set;
    char *name;
    char *email;
};

struct Database {
    struct Address *rows;
    int maxData;
    int maxRows;
};

struct Connection {
    File *file;
    struct Database *db;
};

It is more useful to use single malloc for whole matrix (if it's possible). To do so you should organize your structure with zero length array as the last member:

struct grid {
    int row_count;
    int column_count; 
    int cell_capacity;       
    char data[];
};

In that case you can allocate memory once. For example

int row_count = 2;
int column_count = 3; 
int cell_capacity = 32;

struct grid* g = calloc(1, sizeof(struct grid)+row_count*column_count*cell_capacity);
 
g->row_count = row_count;
g->column_count = column_count;
g->cell_capacity = cell_capacity;

for(int r = 0; r < row_count; ++r)
  for(int c = 0; c < column_count; ++c)
     strcpy(&g->data[r*column_count*cell_capacity + c*cell_capacity], "hello");
// (*)
free(g);

At the (*) point in memory your object will be presented likes the following:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM