RoadRunner RoadRunner - 1 month ago 5
C Question

Dynammically allocating array of multiple structs

I have a bunch of structures declared like this:

typedef struct {
int docid;
int freq;
} pairs_t;

typedef struct {
char *word;
int numlines;
pairs_t *pairs;
int index;
int npairs;
} data_t;

typedef struct {
data_t *data;
int numwords;
} index_t;


Where I want to create an array of structures within
index_t
, where
index_t
will hold information about each element from
data_t
.

I am trying to


  • malloc space for the array
    data_t *data
    within
    index_t
    to hold an array of structures.

  • realloc more space when required for the array of structures.

  • malloc enough space for each element within the array of structures



I have just been playing around with this, and this is what I came up with:

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

int
main(int argc, char *argv[]) {
int initialsize = 1;
int count = 0;

index_t *index;
index->data = (data_t*)malloc(initialsize * sizeof(data_t));

index->data = realloc(index->data, 2 * initialsize);

index->data[count] = malloc(sizeof(data_t));

count++;

return 0;
}


I am just wondering why my mallocing of
index->data[count]
is causing an error. This is no means a proper program, I was just wondering why this isn't working. I am just trying to see If I can get all three of these steps to work before I attempt a bigger program.

The error is:

error: incompatible types when assigning to type "data_t" from type "void *"


Any sort of help would be appreciated.

Answer

why my mallocing of index->data[count] is causing an error

It's wrong because index->data[count] is of the type data_t but not data_t* and so it cannot hold the address returned by malloc()

By the way you need not cast the value of malloc() as it returns void* which is implicitly converted to the type of variable it's getting assigned to

Apart from that, as others have pointed out you didn't initialise the index


here's a way of dealing with your problem:

int initialsize = 1;
int count = 0;

index_t *index;

//allocating memory for index
index = malloc(sizeof(index_t));

//allocating memory for `data`
index->data = malloc(initialsize * sizeof(data_t));

int required_size = 7; //I chose 7 randomly

//reallocating memory for `data`
index->data = realloc(index->data, required_size * sizeof(data_t));

count++;

Further, if you want to allocate memory for pairs_t *pairs; member of one of the elements of data this is how you can do it:

int required_size = 2;

index->data = malloc(required_size * sizeof(data_t));

//for first element of array
index->data[0].pairs = malloc(required_size * sizeof(pairs_t)); 
//you can even realloc
index->data[0].pairs = realloc(index->data[0].pairs, 3 * sizeof(pairs_t));

And by the way, don't forget to free the malloced data at the end of the program


Here's a sample program to sum it all up:

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

typedef struct {
    int docid;
    int freq;
} pairs_t;

typedef struct {
    char *word;
    int numlines;
    pairs_t *pairs;
    int index;
    int npairs;
} data_t;

typedef struct {
    data_t *data;
    int numwords;
} index_t;

int main(int argc, char *argv[]) 
{
    int initialsize = 1;
    int count = 0;

    index_t *index;
    index = malloc(sizeof(index_t));

    int required_size = 1;

    index->data = malloc(required_size * sizeof(data_t));

    //for first element of array
    index->data[0].pairs = malloc(required_size * sizeof(pairs_t)); 
    //you can even realloc
    index->data[0].pairs = realloc(index->data[0].pairs, 1 * sizeof(pairs_t));

    //now you can access the members of pairs this way

    index->data[0].pairs[0].docid = 777;
    index->data[0].pairs[0].freq  = 777;

    printf("docid : %d\nfreq  : %d", index->data[0].pairs[0].docid, index->data[0].pairs[0].freq);

    free(index->data[0].pairs);
    free(index->data);
    free(index);

    count++;

    return 0;
}

output:

docid : 777
freq  : 777

Working sample: https://ideone.com/Bg6aWa

Comments