2017-07-23 106 views
-1
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

可能重複[是未初始化的局部變量最快的隨機數生成器?](https://stackoverflow.com/questions/31739792/is-uninitialized-local-variable-the-fastest-random-number-generator) – LogicStuff

+1

Off topic:'Layer PrevLayer'是按值傳遞的。對PrevLayer進行的任何更改都會複製到一個副本中,並且當PrevLayer超出範圍並被銷燬時,該副本將在該函數結束時丟失。這將是一個非常好的時間來熟悉[什麼是三條法則?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree) – user4581301

+0

感謝user4581301,我我也嘗試將它定義爲'layer * PrevLayer',並將它傳遞給一個地址,但這也不起作用 – lordflashhart

回答

2

有幾個錯誤代碼交織和餵養過彼此進行隔離困難的錯誤中的任何一個。修復其中一個錯誤並且不會注意到它很容易,因爲另一個錯誤會及時取代它。

錯誤1和錯誤2很可能會立即致命,而OP所看到的與訪問無效內存有關。 Column(錯誤1)沒有被分配足夠的存儲空間,並且Input(錯誤2)未被分配任何存儲。錯誤3,PrevLayer通過值,是一個討厭的,但不是因爲錯誤4(導致內存泄漏的不足導致的結果)否定錯誤5(Rule of Three違例),而不是立即致命。

我們將從bug 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字節,而不是SizeNeuron s。 Neuron的大小大於一個字節,所以你沒有分配足夠的內存。

解決方案:使用std::vector<Neuron> Column;畢竟這是C++,因此不需要像在C程序中那樣分配內存。

錯誤2也需要在這裏解決。 Input沒有存儲分配。解決方案:std::vector<double*>;但請注意:這對於現代處理器的速度並沒有太多好處,並且由於Column的大小發生變化,可能導致指針無效。根據需要從Column獲得價值會更好。

for(int i=0;i<Size;i++){ 
     Column[i]=Neuron(LayerSize,LayerSize,LayerSize); 

錯誤2將被暴露在這裏

 Input[i]=&Column[i].Input;      //1 
     PrevLayer.Output[i]=Input[i];      //2 
    } 
} 

蟲蟲3,4和5:通過使用std::vector解決錯誤1和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 
    } 
} 

三的規則和所有破壞邏輯由std::vector

Documentation on std::vector

處理現在,我已經撞壞了這一切的時候,我問了Neuron類的需要。一個vector雙重和計算輸入功能是所有似乎都需要的。