Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resize array of structs within a function

I want to dynamically add new elements to a array of structs. I have added a minimal example that segfaults. I think I have to pass a pointer struct data **arr to the function to reallocate and add new element correctly, but I haven't been able to do it correctly.

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

struct data {
    char s[10];
    int arr[10];
};

void add_one_element(struct data *arr, int *num_elements)
{
  /*increment counter*/
  *num_elements +=1;
  arr = realloc(arr, *num_elements * sizeof(struct data));

  strcpy(arr[*num_elements-1].s, "ABC");
  for(int i = 0; i < 10; i++)
    arr[*num_elements-1].arr[i] = i;
}


int main()
{
   struct data *arr = NULL;
   int num_elements = 0;
   add_one_element(arr, &num_elements);

   printf("arr.s = %s\n", arr[num_elements-1].s);
   for(int i = 0; i < 10; i++)
        printf("arr[%d].arr[%d] = %d\n", num_elements-1, i, arr[num_elements-1].arr[i]);

   free(arr);
   return 0;
}

EDIT 1: Tried to correct the problem. This time I get test(91537,0x7fff79532000) malloc: *** error for object 0x7fff5f5c0ad0: pointer being realloc'd was not allocated. Which suggest that the reallocation failed.

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

struct data {
    char s[10];
    int arr[10];
};

void add_one_element(struct data **arr, int *num_elements)
{
  /*increment counter*/
  *num_elements +=1;
  arr = realloc(arr, *num_elements * sizeof(struct data));

  strcpy(arr[*num_elements-1]->s, "ABC");
  for(int i = 0; i < 10; i++)
    arr[*num_elements]->arr[i] = i;
}


int main()
{
   struct data *arr = NULL;
   int num_elements = 0;
   add_one_element(&arr, &num_elements);
   printf("arr.s => %s\n", arr[num_elements-1].s);
   for(int i = 0; i < 10; i++)
        printf("arr[%d].arr[%d] = %d\n", num_elements-1, i, arr[num_elements-1].arr[i]);
   return 0;
}
like image 206
Allstar Avatar asked Jan 24 '26 06:01

Allstar


1 Answers

You're correct that you need to pass in a struct data ** to your function. You would do it as follows:

void add_one_element(struct data **arr, int *num_elements)
{
  /*increment counter*/
  *num_elements +=1;
  *arr = realloc(*arr, *num_elements * sizeof(struct data));

  strcpy((*arr)[*num_elements-1].s, "ABC");
  for(int i = 0; i < 10; i++)
    (*arr)[*num_elements-1].arr[i] = i;
}

So anyplace you were referencing arr in this function would change to *arr. Note that this expression is parenthesized in order to access the array elements.

Then you call the function like this:

add_one_element(&arr, &num_elements);
like image 152
dbush Avatar answered Jan 26 '26 22:01

dbush



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!