Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

filling dynamically allocated struct inside function

Tags:

c

struct

I'm trying to make a function that accepts a pre-allocated memory pointer as input and fills an array of structs at that location with data. In this example, I expected the output to be:

W 100
L 200

However, the first line is correct, but the second line prints no character and a zero. What am I doing wrong?

typedef struct{
  char word;
  long number;
}record;

void makerec(record** data){
  data[0]->word='W';
  data[0]->number=100;
  data[1]->word='L';
  data[1]->number=200;
}

int main(){
  record* data=(record*)malloc(sizeof(record)*1000);
  makerec(&data);
  printf("%c %ld\n",data[0].word,data[0].number);
  printf("%c %ld\n",data[1].word,data[1].number);
  free(data);
  return 0;
}
like image 353
Mike -- No longer here Avatar asked Dec 19 '25 06:12

Mike -- No longer here


1 Answers

You're not dealing with the right types. Simply change:

void makerec(record** data) {

to:

void makerec(record * data) {

and:

makerec(&data);

to:

makerec(data);

as well as changing data[0]->word='W'; and friends to data[0].word = 'W';

data is already a pointer, and you want to change the thing to which it points, so you can just pass it directly to makerec. You'd pass a pointer to data if you wanted makerec() to make it point to something different, but that's not what you're doing here, so just passing data itself is correct.

Incidental to your main issue, but:

record* data=(record*)malloc(sizeof(record)*1000);

should be:

record* data = malloc(1000 * sizeof *data);
if ( !data ) {
    perror("memory allocation failed");
    exit(EXIT_FAILURE);
}

Notes:

  1. You don't need to (and, to my mind, shouldn't) cast the return value of malloc() and friends

  2. sizeof *data is better than sizeof(record), since it continues to work if the type of data changes, and more importantly, it removes the possibility of you applying the sizeof operator to an incorrect type, which is a common mistake.

  3. Reversing the positions of 1000 and sizeof *data is merely cosmetic, to make the multiple '*'s easier to comprehend.

  4. You should always check the return value of malloc() in case the allocation failed, and take appropriate action (such as exiting your program) if it did.

like image 163
Crowman Avatar answered Dec 20 '25 20:12

Crowman