2016-12-02 4 views
-2

Ich habe diese zwei Klassen und eine dritte Klasse namens "Kreatur", die zwei Konstruktoren hat.Zugriffsverletzung bei Verwendung von löschen

class Neuron 
{ 
public: 
    Neuron(int nWeights); 
    void Mutate(); 

    void calculateOutput(std::vector<Neuron*>* previousLayer); 
    void changeOutput(float output);          // this function is for the input neurons 
    float returnOutput(); 


private: 
    std::vector<float> weights;            // the first weight is the thresholdWeight 
    float output; 
}; 

class NeuralNet 
{ 
public: 
    NeuralNet(std::vector<int> netInfo); 
    ~NeuralNet(); 
    void Mutate(); 

    void CalculateOutputs(); 
    void UpdateInputs(std::vector<float> inputs); 
    void AddLayer(std::vector< Neuron* > *layer); 
    std::vector<float> ReturnOutputs(); 
    std::vector< std::vector< Neuron* >* >* ReturnLayersPointer(); 
private: 
    std::vector< std::vector< Neuron* >* > layers;       // The first layer is the input layer so the outputs of its neurons are given not calculated 
}; 

Die beiden Konstrukteure sind:

creature::creature(vector2D startPosition, float maxSpeed, float radius, std::vector<int> netInfo) 
    : 
position(startPosition), 
maxSpeed(maxSpeed), 
radius(radius) 
{ 
    neuralNet = new NeuralNet(netInfo); 
    nGreensCollected = 0; 

    testMap.resize(MAP_SIZE * MAP_SIZE); 
} 

creature::creature(creature* parent) 
{ 
    position = parent->ReturnPosition(); 
    maxSpeed = parent->ReturnMaxSpeed(); 
    radius = parent->ReturnRadius(); 
    neuralNet = new NeuralNet(*parent->ReturnNeuralNetPointer()); 
    neuralNet->Mutate(); 

    nGreensCollected = 0; 
    testMap.resize(MAP_SIZE * MAP_SIZE); 
} 

Wenn ich versuche, Kreaturen zu löschen, die den ersten Konstruktor kein Problem entsteht, gemacht werden, aber die Kreaturen aus dem zweiten Konstruktor geben Sie mir eine nicht behandelte Ausnahme verwenden. Hier ist der destructor für die Neuralnet Klasse:

NeuralNet::~NeuralNet() 
{ 
    for(int i = 0; i < layers.size(); i++) 
    { 
     for(int j = 0; j < (*layers[i]).size(); j++) 
     { 
      delete (*layers[i])[j]; 
     } 
    } 
} 

Dies ist, wie ich die Kreaturen erstellen, die ich ohne Probleme löschen:

for(int i = 0; i < 10; i++) 
{ 
    vector2D vPosition; 
    vPosition.x = 25000; 
    vPosition.y = 25000; 
    std::vector<int> netInfo; 
    netInfo.push_back(39); 
    netInfo.push_back(39); 
    netInfo.push_back(2); 
    creature* pCreature = new creature(vPosition,1,20,netInfo); 

    creatureSystem->AddCreature(pCreature); 
} 

void CreatureSystem::AddCreature(creature* pNewCreature) 
{ 
    creatures.push_back(pNewCreature); 
} 

Und das ist, wie ich die Kreaturen erstellen, die die Fehler geben wenn gelöscht (die letzten 6 Zeilen):

void CreatureSystem::NaturalSelection() 
{ 
    std::vector<std::pair<int,int>> performances; 
    performances.resize(creatures.size()); 
    for(int i = 0; i < creatures.size(); i++) 
    { 
     std::pair<int,int> temp; 
     temp.second = i; 
     temp.first = creatures[i]->ReturnAndResetGreensCollected(); 
     performances[i] = temp; 
    } 
    std::sort(performances.begin(), performances.end()); 

    int temp = creatures.size()/2; 
    for(int i = 0; i < temp; i++) 
    { 
     if(creatures[performances[i].second] != NULL) 
     { 
      delete creatures[performances[i].second]; 
     } 
    } 
    creatures.erase(creatures.begin(), creatures.begin() + temp); 

    for(int i = 0; i < temp; i++) 
    { 
     creature* pChildCreature = new creature(creatures[i]); 
     AddCreature(pChildCreature); 
    } 
} 

Kreatur Klasse:

class creature 
{ 
private: 
    NeuralNet* neuralNet; 
    /* The inputs represent the r, g, b values of the tiles as shown at CreatureSystem::returnInputs(vector2D position). 
     The outputs are the components of the velocity vector(0.5 is not moving, 1 is moving at full speed in that direction, 
     0 is moving at full speed in the opposite direction). Outputs[0] is for velocity.x and [1] is for velocity.y 
    */ 
    vector2D position; // the center of the creature 
    vector2D velocity; 
    float maxSpeed; 
    float radius; 

    int nGreensCollected; 
public: 
    std::vector<sf::Color> testMap; 

    creature(vector2D startPosition, float maxSpeed, float radius, std::vector<int> netInfo); 
    creature(creature* parent); 
    ~creature(); 

    void Draw(sf::RenderWindow& window, vector2D cameraPosition); 
    vector2D ReturnPosition(); 
    float ReturnMaxSpeed(); 
    float ReturnRadius(); 
    void UpdateNetInputs(std::vector<float> inputs); 
    void CalculateNetOutputs(); 
    void UpdateVelocity(); 
    void UpdatePosition(); 
    void UpdateTestMap(std::vector<sf::Color>* map); 
    void CheckIsOnGreen(); 
    std::vector<sf::Color>* ReturnMapPointer(); 
    NeuralNet* ReturnNeuralNetPointer(); 
    int ReturnAndResetGreensCollected(); 
    //std::vector<float> returnOutputs(); 

}; 

Fehlertext: Unbehandelte Ausnahme bei 0x6c7bad4a (msvcp100d.dll) in Evolution.exe: 0xC0000005: Zugriff auf Schreibfehler 0xfeeefef2.

+1

Sie verwenden eine * Menge * von Zeigern. Sie sollten wahrscheinlich versuchen, das zu stoppen. Je weniger Zeiger Sie haben, desto weniger Chancen gibt es, dass etwas schief geht. Zum Beispiel macht es Ihr 'NeuralNet :: layers'-Mitglied oft nicht sinnvoll, einen Vektor von Zeigern auf Vektoren zu haben. –

+0

Wenn niemand das Problem sieht, werde ich tun, was Sie empfehlen. –

+0

Kannst du uns die Deklaration für Kreatur zeigen? Auch ein Schuss in die Dunkelheit kannst du den Neuron Destruktor virtuell machen? EDIT: Realised Kreatur kann kein Kind auf Neuron sein können Sie uns immer noch die Erklärung der Kreatur zeigen? – Eddge

Antwort

0

Ich will hinzufügen, Kommentare, wo die Fragen sind aber hier ist der Code:

void CreatureSystem::NaturalSelection() 
{ 
    std::vector<std::pair<int,int>> performances; 
    performances.resize(creatures.size()); 
    for(int i = 0; i < creatures.size(); i++) 
    { 
     std::pair<int,int> temp; 
     temp.second = i; 
     temp.first = creatures[i]->ReturnAndResetGreensCollected(); 
     performances[i] = temp; 
    } 
    std::sort(performances.begin(), performances.end()); 

    int temp = creatures.size()/2; 
    for(int i = 0; i < temp; i++) 
    { 
     if(creatures[performances[i].second] != NULL) 
     { 
      // Second could be > temp 
      delete creatures[performances[i].second]; 
     } 
    } 
    // Essential erasing indices 0 - temp, but if second was greater then temp 
    // you are leaking memory, and you have recently freed pointers in your list 
    creatures.erase(creatures.begin(), creatures.begin() + temp); 
    // if size was 5 temp is 2 due to truncation, you could possibly be missing a creature here when setting a parent. 
    for(int i = 0; i < temp; i++) 
    { 
     // Could be a freed pointer therefore you are accessing uninitialized memory causing your exception 
     creature* pChildCreature = new creature(creatures[i]); 
     AddCreature(pChildCreature); 
    } 
} 

Da Sie möglicherweise nicht auf den Zeiger in einem Bereich von 0 löschen Aufruf - Temp (von Lebewesen), sind Sie möglicherweise Indizes von Zeigern zu löschen, die noch vorhanden sind, und möglicherweise Undichte Speicher, Die einfachste Methode, um dies zu testen ory wäre, dies zu tun:

dann durchlaufen und löschen Sie die Indizes, die jetzt null sind.

0

Zuerst ist Ihr Code wirklich schmutzig, ich suggest Sie iterators verwenden, um weitere Probleme zu vermeiden, und vielleicht sollten Sie shared_ptr für die "Kreaturen" verwenden, auf diese Weise müssen Sie es nicht im Destruktor löschen.

Zweitens Sie Hauptproblem ist, dass Sie einen schmutzigen Zeiger zu löschen versuchen, ist dies, weil Sie es zuvor in der „Selektion“ von der Linie gelöscht:

delete creatures[performances[i].second]; 
+0

Wo sollte ich Iteratoren verwenden? –

+0

Wenn Sie Elemente in einem Container ausfüllen oder löschen: Beispiel: http://www.learncpp.com/cpp-tutorial/16-3-stl-iterators-overview/ – Rama

Verwandte Themen