I have the following struct:
typedef struct ann_t {
uint32_t xs;
uint32_t hs;
uint32_t ys;
float *x;
float *h;
float *y;
float **wxh;
float **why;
} ann_t;
Initialized in the following way:
ann_t* ann_init(uint32_t xs, uint32_t hs, uint32_t ys) {
ann_t *ann = malloc(sizeof(ann_t));
ann->xs = xs;
ann->hs = hs;
ann->ys = ys;
ann->x = calloc(xs, sizeof(float));
ann->h = calloc(hs, sizeof(float));
ann->y = calloc(ys, sizeof(float));
ann->wxh = calloc(xs, sizeof(float*));
ann->why = calloc(hs+1, sizeof(float*));
int i, j;
for(i = 0; i < xs; i++) {
ann->wxh[i] = malloc(hs * sizeof(float));
}
for(i = 0; i < hs+1; i++) {
ann->why[i] = malloc(ys * sizeof(float));
}
// printf("%p\n", ann->x);
return ann;
}
Including this code in another program:
...
ann_t *ann = ann_init(25, 10, 4);
// printf("%p\n", ann->x);
ann->x[0] = 1.0;
...
The result is:
Segmentation fault (core dumped)
Using valgrind:
==26436== Use of uninitialised value of size 8
...
==26436==
==26436== Invalid write of size 4
...
==26436== Address 0x4c3a78000000000 is not stack'd, malloc'd or (recently) free'd
I tried to reproduce this in a smaller program but couldn't.
Changing the struct to have uint64_t
instead of uint32_t
solves the problem.
Printing the pointer ann->x
inside ann_init
I get 0x55601051f080 and outside 0x1051f08000000000.
Why does this happen?
EDIT: Found the culprit in one of the included files:
#pragma pack(1)
Still not sure why this causes the problem.
If I was doing pointer arithmetic to access the struct fields this would make sense but I'm accessing the struct field by name so why does it calculate the wrong value?
Why is it fine inside the init function but outside it the access fails?