Michael Gierer
Michael Gierer

Reputation: 453

C - Multiple malloc's for a struct-array inside a function

I've got a theoretical question on allocating memory for structs. Consider the following code IN THE MAIN FUNCTION:

I have the following struct:

typedef struct {
    char *descr = NULL;
    DWORD id = 0x00FFFF00;
    int start_byte = 0;
    int end_byte = 0;
    double conversion_factor = 0.0;
} CAN_ID_ENTRY;

I want an array of this structs, so I'm allocating a pointer to the first struct:

can_id_list = (CAN_ID_ENTRY **)malloc(sizeof(CAN_ID_ENTRY));

And then I'm allocating memory for the first struct can_id_list[0]:

can_id_list[0] = (CAN_ID_ENTRY *)malloc(sizeof(CAN_ID_ENTRY));

Now the problem is, that I don't know HOW MANY of these structs I need (because I'm reading a CSV-File and I don't know the amount of lines/entries). So I need to enlarge the struct-pointer can_id_list for a second one:

can_id_list = (CAN_ID_ENTRY **)malloc(sizeof(CAN_ID_ENTRY));

And then I'm allocating the second struct can_id_list[1]:

can_id_list[1] = (CAN_ID_ENTRY *)malloc(sizeof(CAN_ID_ENTRY));
can_id_list[1]->id = 6;

Obviously, this works. But why? My point is the following: Normally, malloc allocates memory in one block in the memory (without gaps). But if another malloc is done BEFORE I'm allocating memory for the next struct, there is a gap between the first and the second struct. So, why can I access the second struct via can_id_list[1]? Does the index [1] store the actual address of the struct, or does it just calculate the size of the struct and jumps to this address beginning on the offset of the struct-pointer can_id_list (-> can_id_list+<2*sizeof(CAN_ID_ENTRY))?

Well, my real problem is, that I need to do this inside a function and therefore I need to pass the pointer of the struct to the function. But I don't know how to do this, because can_id_list is already a pointer ... and the changes must also be visible in the main method (that's the reason i need to use pointers).

The mentioned function is this one:

int load_can_id_list(char *filename, CAN_ID_ENTRY **can_id_list);

But is the parameter CAN_ID_ENTRY **can_id_list correct? And how do i pass the struct-array into this function? And how can i modify it inside??

Any help would be great!

EDIT: Casting malloc returns - Visual Studio forces me to do that! (Because it's a C++ project i think)

Upvotes: 0

Views: 343

Answers (1)

sudo
sudo

Reputation: 5804

As the comments already said, the source of your confusion is can_id_list = (CAN_ID_ENTRY **)malloc(sizeof(CAN_ID_ENTRY)); allocating the wrong amount of memory. It probably gave you space for a few pointers to be stored, not just one. Should be can_id_list = (CAN_ID_ENTRY **)malloc(sizeof(CAN_ID_ENTRY*));.

To answer the question at the end,

But is the parameter CAN_ID_ENTRY **can_id_list correct? And how do i pass the struct-array into this function? And how can i modify it inside??

If you want to enlarge the size of the array within another function, you need to pass CAN_ID_ENTRY*** pr so you can set *ptr = realloc(...) inside as needed. Realloc may give you the new chunk of memory at a different address, so you can't simply pass in a CAN_ID_ENTRY** ptr then do realloc(ptr). See https://www.tutorialspoint.com/c_standard_library/c_function_realloc.htm

Upvotes: 2

Related Questions