C语言malloc分配已用堆内存致结构体值异常问题
结构体成员莫名被修改的问题排查与解决
问题现象
执行代码后,network.layers[0].weights.column_size的值在调用create_matrix后意外从2变为0:
layer l = linear(2, 3); neural_network network = create_network(); add_layer(&network, &l); printf("Before: %llu\n", network.layers[0].weights.column_size); matrix i = create_matrix(2, 1); printf("After: %llu\n", network.layers[0].weights.column_size);
输出结果:
Before: 2 After: 0
地址打印显示,network.layers[0].weights.column_size的内存地址与create_matrix中mat.array的地址完全重合,说明堆内存被非法覆盖:
Address of network.layers[0].weights.column_size: 0x600000b4c010 Before: 2 Address of mat.array: 0x600000b4c010 After: 0
问题根源
add_layer函数的内存分配计算错误:
void add_layer(neural_network *network, layer *l) { network->layers = realloc(network->layers, ++network->number_of_layers); network.layers[network->number_of_layers - 1] = *l; }
realloc的第二个参数需要传入总字节数,但这里只传入了层数(++network->number_of_layers),而每个layer结构体的大小远大于1字节。这导致分配的内存空间严重不足,赋值*l到network.layers数组时发生堆内存越界写入,破坏了后续malloc的内存布局,最终让create_matrix返回的mat.array指针覆盖了目标结构体成员的值。
修复代码
修改add_layer函数,正确计算所需内存大小:
void add_layer(neural_network *network, layer *l) { network->number_of_layers++; // 分配 sizeof(layer) * 层数 的字节数 network->layers = realloc(network->layers, sizeof(layer) * network->number_of_layers); // 推荐:检查内存分配是否成功 if (network->layers == NULL) { perror("Failed to reallocate memory for layers"); exit(EXIT_FAILURE); } network->layers[network->number_of_layers - 1] = *l; }
另外,create_network中初始分配0大小内存可优化为直接初始化layers为NULL(realloc(NULL, size)等价于malloc(size)):
neural_network create_network() { neural_network network = { .number_of_layers = 0, .layers = NULL }; return network; }
额外提示
- 务必检查
malloc/realloc的返回值,避免内存分配失败引发后续未知错误 - 当前代码中
layer包含matrix结构体,matrix持有堆内存指针,属于浅拷贝。后续如果需要释放内存,要注意避免重复释放或内存泄漏问题
内容的提问来源于stack exchange,提问作者Aayush
相关产品推荐
相关产品推荐

