У меня есть следующая структура:
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;
Инициализируется следующим образом:
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;
}
Включение этого кода в другую программу:
...
ann_t *ann = ann_init(25, 10, 4);
// printf("%p\n", ann->x);
ann->x[0] = 1.0;
...
результат:
Ошибка сегментации (ядро сброшено)
Использование valgrind:
== 26436 == Использование неинициализированного значения размера 8
...
== 26436 ==
== 26436 == Неверная запись размера 4
...
== 26436 == Адрес 0x4c3a78000000000 не в стеке, mallo c 'd или (недавно) free'd
Я пытался воспроизвести это в меньшей программе, но не смог .
Изменение структуры на uint64_t
вместо uint32_t
решает проблему.
Печать указателя ann->x
внутри ann_init
Я получаю 0x55601051f080 и снаружи 0x1051f08000000000 .
Почему это происходит?
РЕДАКТИРОВАТЬ: Найден преступник в одном из включенных файлов:
#pragma pack(1)
До сих пор не уверен, почему этот ка SES проблема.
Если бы я делал арифметику указателей c для доступа к полям структуры, это имело бы смысл, но я обращаюсь к полю структуры по имени, так почему же оно вычисляет неправильное значение?
Почему это нормально внутри функции инициализации, но за ее пределами доступ не удается?