C++神经网络程序出现Segmentation Fault及指针错误求助
神经网络C++程序段错误与指针错误的排查与修复
核心错误分析
1. 动态数组创建错误
在Layer::calcOutput函数中,创建动态数组时误用了圆括号:
double *weightedInputs = new double(numNodesOut);
这行代码的作用是创建单个double变量并将其初始化为numNodesOut的值,而非创建长度为numNodesOut的数组。后续用delete [] out释放非数组指针,会触发munmap_chunk(): invalid pointer错误。
正确写法需使用方括号创建数组:
double *weightedInputs = new double[numNodesOut];
2. 数组越界访问
在calcOutput的内层循环中,错误地用输出节点索引访问输入数组:
weightedInput += inputs[nodeOut] * nodes[nodeOut].weights[nodeIn];
输入数组inputs的长度为numNodesIn(示例中为3),但nodeOut的取值范围是0到numNodesOut-1(示例中为0到3),当nodeOut >= numNodesIn时,会访问inputs的越界内存,触发段错误。
正确写法需用输入节点索引访问输入数组:
weightedInput += inputs[nodeIn] * nodes[nodeOut].weights[nodeIn];
修正后的完整代码
Node类与Layer类修正版
#include <iostream> #include <vector> #include <cstdlib> #include <ctime> using namespace std; class Node{ public: vector<double> weights; double biasN; Node(int numNodeIn){ for (int i = 0; i < numNodeIn; i++) { double z = (double)(rand() % 100) / 100; cout << z << "##" << endl; weights.push_back(z); } biasN = (double)(rand() % 1000) / 100; cout << biasN << "#" << endl; } }; class Layer{ public: int numNodesIn, numNodesOut; vector<Node> nodes; Layer(int NodesIn, int NodesOut){ this->numNodesIn = NodesIn; this->numNodesOut = NodesOut; for (int i = 0; i < numNodesOut; i++) { Node N(numNodesIn); nodes.push_back(N); } } double* calcOutput(double inputs[]){ // 修正:使用方括号创建动态数组 double *weightedInputs = new double[numNodesOut]; for (int nodeOut = 0; nodeOut < numNodesOut; nodeOut++) { double weightedInput = nodes[nodeOut].biasN; for (int nodeIn = 0; nodeIn < numNodesIn; nodeIn++) { // 修正:使用nodeIn作为输入数组索引 weightedInput += inputs[nodeIn] * nodes[nodeOut].weights[nodeIn]; } weightedInputs[nodeOut] = weightedInput; } return weightedInputs; } };
主函数修正版
int main() { srand(static_cast<unsigned>(time(0))); const int hiddenLayers = 4; Layer layer(3, hiddenLayers); double inp[3] = {2.5, 2.5, 1.5}; double *out = layer.calcOutput(inp); for (int i = 0; i < hiddenLayers; i++) { cout << out[i] << endl; } delete [] out; return 0; }
额外建议
- 优先使用
std::vector<double>替代原生动态数组,自动管理内存,避免手动new/delete的错误。 - 添加边界检查(如
assert(nodeIn < numNodesIn)),提前发现越界问题,降低调试难度。
内容的提问来源于stack exchange,提问作者Soumish Das
相关产品推荐
相关产品推荐

