Allstar Allstar - 3 months ago 14
C Question

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;
}

Answer

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);
Comments