I came across the problem where a dynamic array of structures is properly initialized and filled with data in a function from an included file, but an attempt to access the content of the array causes segmentation faults in the main function even though the pointer was defined globally. Please have a look at the example below:
my_struct.h
typedef struct my_struct {
int one;
int two;
} my_struct_t;
void update_my_struct(my_struct_t*, int);
my_struct.c
#include <stdlib.h>
#include <stdio.h>
#include "my_struct.h"
void
update_my_struct(my_struct_t *my_s, int num)
{
int i;
for (i = 0; i < num; i++ ) {
my_s = realloc(my_s, sizeof(my_struct_t)*(i+1));
my_s[i].one = 1*i;
my_s[i].two = 2*i;
}
printf(" my_s[0] one: %d two: %d\n", my_s[0].one, my_s[0].two);
}
main.c
#include <stdlib.h>
#include <stdio.h>
#include "my_struct.h"
my_struct_t *my_structs;
void
main(void)
{
int i;
update_my_struct(my_structs, 4);
for (i = 0; i < 4; i++)
printf(" %d. one = %d, two = %d\n", i, my_structs[i].one, my_structs[i].two);
free(my_structs);
}
Compile and run:
$ gcc main.c my_struct.c
$ ./a.out
my_s[0] one: 0 two: 0
Segmentation fault (core dumped)
I checked with gdb and the seg fault occurs in main
, so it puzzles me how come the dynamic array can be accessed in the included function, but in the main function even though the pointer was declared in main.c
. I will appreciate some helpful hints and comments on this issue.
update
Following up on EML's answer I changed the code of the update function to:
void
update_my_struct(my_struct_t *my_s, int num)
{
int i;
for (i = 0; i < num; i++ ) {
if (my_s == NULL)
my_s = (my_struct_t *) malloc(sizeof(my_struct_t));
else
my_s = (my_struct_t *) realloc(my_s, sizeof(my_struct_t)*(i+1));
my_s[i].one = 1*i;
my_s[i].two = 2*i;
}
printf(" my_s[3] one: %d two: %d\n", my_s[3].one, my_s[3].two);
}
Seg fault still occurs:
$ ./a.out
my_s[3] one: 3 two: 6
Segmentation fault (core dumped)
Valgrind did not provide me with any insightful information, here is the snippet of its output:
==5301== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==5301== Command: ./a.out
==5301==
my_s[3] one: 3 two: 6
==5301== Invalid read of size 4
==5301== at 0x40118F: main (in a.out)
==5301== Address 0x4 is not stack'd, malloc'd or (recently) free'd
==5301==
==5301==
==5301== Process terminating with default action of signal 11 (SIGSEGV): dumping core
...