C++ Can';t将成员变量地址分配给指针
代码中存在多个bug,它们相互交织、相互补充,使得隔离任何一个bug都很困难。很容易修复其中一个bug而不注意到它,因为另一个bug很快就会取代它 Bug 1和Bug 2很可能立即致命,OP看到了这一点,因为它们与访问无效内存有关<代码>列(错误1)未分配足够的存储空间,C++ Can';t将成员变量地址分配给指针,c++,pointers,member-variables,C++,Pointers,Member Variables,代码中存在多个bug,它们相互交织、相互补充,使得隔离任何一个bug都很困难。很容易修复其中一个bug而不注意到它,因为另一个bug很快就会取代它 Bug 1和Bug 2很可能立即致命,OP看到了这一点,因为它们与访问无效内存有关列(错误1)未分配足够的存储空间,输入(错误2)未分配任何存储空间。Bug 3,PrevLayer通过值传递,是一个讨厌的问题,但由于Bug 4(不充分的析构函数导致内存泄漏)否定了Bug 5(违规),因此不会立即致命 我们将从Bug3开始,因为它首先在代码中表示,尽管
输入
(错误2)未分配任何存储空间。Bug 3,PrevLayer
通过值传递,是一个讨厌的问题,但由于Bug 4(不充分的析构函数导致内存泄漏)否定了Bug 5(违规),因此不会立即致命
我们将从Bug3开始,因为它首先在代码中表示,尽管之后会看到它。此外,这是一个真正的快速修复
}
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
};
Bug 3是通过值传递的PrevLayer
。这将复制源层
,对PrevLayer
的任何修改都不会在源层
中看到。解决方案:通过引用传递<代码>图层(int LayerSize、Layer和PrevLayer)
下面是bug 1:
Size=LayerSize;
malloc
分配字节,而不是对象。这有两种方法:1Neuron
的构造函数未运行,因此您有未初始化的Neuron
s。2.您有Size
字节,而不是Size
Neuron
sNeuron
的大小大于一个字节,因此您没有分配足够的内存
解决方案:使用std::vector列代码>毕竟是C++,所以不需要像C程序那样分配内存。
Bug 2也需要在这里解决。没有为输入分配存储空间。解决方案:std::vector代码>但请注意:这对现代处理器的速度没有多大好处,并且允许由于列
的大小改变而导致指针无效。您最好根据需要从列
中获取值
Column=(Neuron*)malloc(Size);
错误3、4和5:已通过使用std::vector
解决错误1和2解决
好的。那么,我们如何将所有这些解决方案放在一起呢
Input[i]=&Column[i].Input; //1
PrevLayer.Output[i]=Input[i]; //2
}
}
类神经元{
公众:
神经元(int-PrevColumnSize、int-ThisColumnSize、int-NextColumnSize);
双输入;//每个神经元的输入
};
类层{
//尺寸消失了vector知道它有多大。
std::vector Column;//神经元列
std::vector Output;//真是个坏主意。强烈建议重新考虑
公众:
图层(int LayerSize);
Layer(int LayerSize,Layer&PrevLayer);//现在获取一个引用
双运算符[](大小索引)//以安全访问输入。
{
返回列[索引]。输入;
}
};
Layer::Layer(int LayerSize、Layer和PrevLayer){
对于(int i=0;i主题外的可能副本:Layer-PrevLayer
是传递值。您对PrevLayer
所做的任何更改都将复制到一个副本中,并在PrevLayer
超出范围并被销毁时丢失。这将是一个非常好的时间来熟悉不要使用malloc在C++中,你可以避免很多bug,比如当你想要X元素时分配X字节。这就是为什么我把它称为“偏离主题”。这就是接下来你要遇到的两个错误。你现在的bug是微不足道的。也许为什么没有人出来告诉你。玩得长一点,也许做一个,你自己会看到。开始思考。其中,您有4个相互竞争的bug。这使得分类有点困难,因为您可以修复其中任何一个,程序可能仍然会死亡。
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
}
}
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
}
}