Выделение памяти для matrix
struct с некоторыми значениями пары [row, column]
для функции create_matrix
изменяет значения указателя layer->values
, который не имеет отношения к выделяемой структуре matrix
.
Некоторые протестированы [row, column]
значения:
[1, 2]
[2, 2]
вывод gdb для [2,2], т.е. create_matrix(2, 2)
:
(gdb) print *prev_layer
$1 = {
nodes = 2,
weights = 0xb6438030,
biases = 0xb6438060,
values = 0xb6438080
}
(gdb) n
(before allocation): 0xb6438080
50 weights = create_matrix(2, 2);
(gdb) n
51 if (!weights)
(gdb) print *prev_layer
$2 = {
nodes = 2,
weights = 0xb6438030,
biases = 0xb64380b0, <- this changes
values = 0xb64380c0 <- this changes
}
(gdb)
Сверху кажется, что он назначает два последних указателя, связанных с памятью распределение для двух последних членов структуры. Иногда даже NULL
указатель
Вывод программы для [2,2]
:
Values of prev_layer->values
(before allocation): 0xb6438080
(after allocation): 0xb64380c0
Используемый код:
#include <stdlib.h>
#include <stdio.h>
typedef struct matrix {
int rows;
int cols;
double **m;
} matrix;
typedef struct layer {
int nodes;
matrix *weights;
matrix *biases;
matrix *values;
} layer;
matrix *create_matrix(int rows, int cols) {
matrix *ret = malloc(sizeof(matrix));
if (!ret)
return NULL;
double **m = malloc(rows * sizeof(double *));
if (!m)
return NULL;
for (int c = 0; c < rows; c++) {
m[c] = calloc(cols, sizeof(double));
if (!m[c]) {
return NULL;
}
}
ret->rows = rows;
ret->cols = cols;
ret->m = m;
return ret;
}
layer *create_layer(int nodes, const layer *prev_layer) {
matrix *weights, *biases;
/* Just after allocation it changes pointer of
* prev_layer->bias and prev_layer->values
* to last to matrix row allocations
* bug works with values in ordered pair [row, col] => [1,2], [2,2],
* doesn't with when used values like [5,3]
* */
if (prev_layer)
printf("(before allocation): %p\n", prev_layer->values);
weights = create_matrix(1,2);
if (!weights)
return NULL;
if (prev_layer)
printf("(after allocation): %p\n", prev_layer->values);
biases = create_matrix(1, nodes);
if (!biases)
return NULL;
matrix *values = create_matrix(1, nodes);
if (!values)
return NULL;
layer *ret = malloc(sizeof(layer *));
if (!ret)
return NULL;
ret->nodes = nodes;
ret->weights = weights;
ret->biases = biases;
ret->values = values;
return ret;
}
int main() {
int nodes[] = {2, 2};
layer *p1 = create_layer(2, NULL);
layer *p2 = create_layer(2, p1);
return 0;
}
Компилятор: clang 9.0 0,0