Il y a plusieurs bugs dans le code entremêlés et se nourrissant les uns des autres pour faire isoler l'une des bogues difficiles. Il est facile de corriger l'un des bugs et de ne pas le remarquer car un autre bogue prend rapidement sa place.
Les bugs 1 et 2 sont probablement immédiatement fatals et ce que OP voit comme ils ont à voir avec l'accès à la mémoire invalide. Column
(bug 1) n'est pas alloué suffisamment de stockage et Input
(bug 2) ne se voit allouer aucun stockage. Le bogue 3, PrevLayer
passé par valeur, est une nuisance, mais pas immédiatement mortel en raison du bogue 4 (résultat insuffisant de l'extracteur dans la fuite de mémoire) nociant le bug 5 (violation Rule of Three).
Commençons par le bogue 3 car il est représenté en premier dans le code même s'il sera vu après. De plus, c'est une solution très rapide.
Layer::Layer(int LayerSize, Layer PrevLayer){
Bug 3 est PrevLayer
est passé par valeur. Cela fait une copie de la source Layer
et aucune modification à PrevLayer
ne sera pas vu dans la source Layer
. Solution: Passer par référence. Layer(int LayerSize, Layer & PrevLayer)
Size=LayerSize;
Voici bug 1:
Column=(Neuron*)malloc(Size);
malloc
octets, alloue pas des objets. Cela vous permet de deux manières: 1. Le constructeur de Neuron
n'est pas exécuté, vous avez donc Neuron
non initialisé. 2. Vous avez Size
octets, pas Size
Neuron
s. La taille de Neuron
est supérieure à un octet. Vous n'avez donc pas alloué suffisamment de mémoire.
Solution: Utilisez std::vector<Neuron> Column;
C++ est après tout, il n'est donc pas nécessaire d'allouer de la mémoire comme vous le feriez dans un programme C.
Le bogue 2 doit également être traité ici. Aucun stockage n'a été alloué pour Input
. Solution: std::vector<double*>;
Mais note: cela ne vous fait pas beaucoup de faveurs en ce qui concerne la vitesse sur un processeur moderne et permet la possibilité que les pointeurs peuvent être rendus invalides en raison d'un changement de la taille de Column
. Il vaut mieux simplement obtenir la valeur de Column
au besoin.
for(int i=0;i<Size;i++){
Column[i]=Neuron(LayerSize,LayerSize,LayerSize);
Bug 2 sera exposé ici
Input[i]=&Column[i].Input; //1
PrevLayer.Output[i]=Input[i]; //2
}
}
Bugs 3, 4 et 5: déjà résolu en utilisant std::vector
pour résoudre les bugs 1 et 2.
D'accord. Alors, comment pouvons-nous mettre toutes ces solutions ensemble?
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
}
}
La règle de trois et toute logique de destruction est assurée par std::vector
Documentation on std::vector
Maintenant que je l'ai défoncé tout cela, je remets en question la nécessité d'une classe Neuron
. Un vector
de double et une fonction pour calculer l'entrée est tout ce qui semble être nécessaire.
Copie possible de [La variable locale non initialisée est-elle le générateur de nombres aléatoires le plus rapide?] (Https://stackoverflow.com/questions/31739792/is-ininitialized-local-variable-the-fastest-random-number-generator) – LogicStuff
Hors sujet: 'Layer PrevLayer' est passé par valeur. Toutes les modifications que vous apportez à 'PrevLayer' sont faites à une copie et seront perdues à la fin de cette fonction quand' PrevLayer' sort de la portée et est détruit. Ce serait un très bon moment pour vous familiariser avec [Quelle est la règle de trois?] (Https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – user4581301
Merci user4581301, je J'ai aussi essayé de le définir comme 'layer * PrevLayer', et de lui passer une adresse, mais cela ne fonctionnait pas non plus – lordflashhart