无法将成员变量地址分配给指针

时间:2017-07-23 20:28:06

标签: c++ pointers member-variables

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

};

1 个答案:

答案 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 } }

处理

Documentation on std::vector

现在我已经把这一切都搞砸了,我质疑是否需要std::vector课程。一个Neuron的double和一个计算输入的函数似乎都是必需的。