Layer::Layer(int LayerSize, Layer PrevLayer){
Size=LayerSize;
Column=(Neuron*)malloc(Size);
for(int i=0;i<Size;i++){
Column[i]=Neuron(LayerSize,LayerSize,LayerSize);
Input[i]=&Column[i].Input; //1
PrevLayer.Output[i]=Input[i]; //2
}
我试图让Input[i]
指向相应神经元的输入。虽然内存地址看起来是正确的,但当我尝试在行//1
分配成员变量Input的地址值时,程序崩溃了。知道什么是错的,或者我可以使用更好的方法吗?
以下是具有相关成员的课程
}
class Neuron{
public:
Neuron(int PrevColumnSize, int ThisColumnSize, int NextColumnSize);
//Constructor: Generates a Neuron with random values
double Input; //input of each neuron
};
class Layer{
private:
int Size; //Number of Neurons in the layer
public:
Layer(int LayerSize); //Constructor; Layer with no attached layers; used at the start of a network
Layer(int LayerSize, Layer PrevLayer);
//Constructor; Layer which attaches itself to the next, and the previous layers; unused
Neuron* Column; //Column of Neurons
double** Input; //Inputs to Neurons
};
答案 0 :(得分:2)
代码中有几个错误混合在一起并相互隔离,以便将任何一个错误隔离开来。修复其中一个错误很容易,而不会注意到它,因为另一个错误会立即取而代之。
错误1和2可能会立即致命,OP正在看到它们与访问无效内存有关。 Column
(错误1)未分配足够的存储空间,Input
(错误2)未分配任何存储空间。错误3,PrevLayer
通过值传递,是一个令人讨厌的问题,但由于错误4(导致内存泄漏不足导致内存泄漏)导致错误5(Rule of Three违规),因此不会立即致命。
我们将从错误3开始,因为它首先在代码中表示,即使它将在之后被看到。此外,这是一个非常快速的解决方案。
Layer::Layer(int LayerSize, Layer PrevLayer){
错误3是PrevLayer
按值传递。这样就会在源Layer
中看到源PrevLayer
的副本以及对Layer
的任何修改。解决方案:通过引用传递。 Layer(int LayerSize, Layer & PrevLayer)
Size=LayerSize;
这是错误1:
Column=(Neuron*)malloc(Size);
malloc
分配字节,而不是对象。这有两种方法:1。Neuron
的构造函数未运行,因此您有未初始化的Neuron
。 2.您有Size
个字节,而不是Size
Neuron
个。 Neuron
的大小大于一个字节,因此您没有分配足够的内存。
解决方案:使用std::vector<Neuron> Column;
毕竟这是C ++,所以不需要像在C程序中那样分配内存。
Bug 2也需要在这里解决。没有为Input
分配存储空间。解决方案:std::vector<double*>;
但请注意:对于现代处理器的速度而言,这并没有给你带来许多好处,并且由于{{1}的大小变化,指针可能会变得无效}}。只需根据需要从Column
获取值,您就会好得多。
Column
Bug 2将在此处公开
for(int i=0;i<Size;i++){
Column[i]=Neuron(LayerSize,LayerSize,LayerSize);
错误3,4和5:使用 Input[i]=&Column[i].Input; //1
PrevLayer.Output[i]=Input[i]; //2
}
}
解决了错误1和2已经解决了。
好的。那么我们如何将所有这些解决方案放在一起呢?
std::vector
三条规则和所有销毁逻辑由class Neuron{
public:
Neuron(int PrevColumnSize, int ThisColumnSize, int NextColumnSize);
double Input; //input of each neuron
};
class Layer{
// Size is gone. vector knows how big it its.
std::vector <Neuron> Column; //Column of Neurons
std::vector <double*> Output; // really bad idea. Strongly recommend a rethink
public:
Layer(int LayerSize);
Layer(int LayerSize, Layer &PrevLayer); // now takes a reference
double operator[](size_t index) // to safely access Input.
{
return Column[index].Input;
}
};
Layer::Layer(int LayerSize, Layer &PrevLayer){
for(int i=0;i<LayerSize;i++){
Column.emplace_back(LayerSize,LayerSize,LayerSize);
}
// these steps must be separated and Column must never change size or
// these pointers are toast
for (Neuron & column: Column)
{
PrevLayer.Output[i]=&column.Input; // This has a lot of potential for failure
// Strongly recommend a rethink
}
}
现在我已经把这一切都搞砸了,我质疑是否需要std::vector
课程。一个Neuron
的double和一个计算输入的函数似乎都是必需的。