NathanielJPerkins NathanielJPerkins - 1 month ago 6
C Question

Dynamically allocated array of structs passed to function and accessed with indexing

I'm trying to dynamically allocate an array of structs by passing the pointer to a function. I need to access the array using indexing. I've got a similar proccess working without passing to a function. I have a simple struct called Account that only has one member, accountNo. Listed below is the relevant malloc call

int8_t dynamicStruct(struct Account **all_accounts,int8_t num_accounts){
*all_accounts = (struct Account*)malloc(sizeof(struct Account)*num_accounts);
}


The variable all_accounts is initialized and called with the following snippet, with num_accounts at this point being 10;

struct Account *all_accounts_dyn;
dynamicStruct(&all_accounts_dyn,num_accounts);


Accessing the member variable accountNo with the following method

all_accounts[i]->accountNo = i;


The program compiles fine, manages to allocate the memory, but segfaults upon accessing a member (num_accounts = 10).

Compiled with

gcc -std=gnu99 -Wall -Werror structify.c -o structify


"Small self contained example"

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

struct Account{
int8_t accountNo;
};
int8_t dynamicStruct(struct Account **all_accounts,int8_t num_accounts);

int main(){
struct Account *all_accounts_dyn;
int8_t num_accounts = 10;
dynamicStruct(&all_accounts_dyn,num_accounts);
return 1;
}
int8_t dynamicStruct(struct Account **all_accounts,int8_t num_accounts){
*all_accounts = (struct Account*)malloc(sizeof(struct Account)*num_accounts);
for(int i = 0; i<num_accounts;i++){
printf("initializing %d\n",i);
all_accounts[i]->accountNo = i;
}
return 1;
}

Answer

When you have struct my_struct;, you access the members like this:

mystuff = my_struct.stuff;

But when you have a pointer to a struct struct *my_struct;, you do:

mystuff = my_struct->stuff;

This is equivalent to:

mystuff = (*my_struct).stuff;

In other words, you have to dereference the pointer to struct before you can access its member fields.

When you allocate memory for 10 structs:

*all_accounts = (struct Account*)malloc(sizeof(struct Account)*num_accounts);

and then access with array notation, you have all_accounts[i] ==> *(all_accounts + i). So, all_accounts[i] is a struct, not a pointer to a struct, and must be accessed with the dot operator.

Comments