为函数分配matrix
具有[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
用于计算分配大小的类型在以下情况中不正确:
layer *ret = malloc(sizeof(layer *)); // should be sizeof(layer)
您分配指针的大小,而不是结构的大小。
为避免此类愚蠢的错误,可以直接使用目标指针类型:
layer *ret = malloc(sizeof(*ret));
或者,您可以使用分配包装器宏,并依靠编译器来检测不匹配的类型:
#define ALLOC(t) ((t *)calloc(1, sizeof(t)))
#define ALLOC_ARRAY(t, n) ((t *)calloc(n, sizeof(t)))
layer *ret = ALLOC(layer);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句