0

I am trying to build a little game "snake" playing by a neural network. I created 2 classes, one for the neural network and another one for the game. The game has an instance of the class neural network and I used an unique_ptr to avoid a basic pointer and to train with it. The neural network class has 2 mains private variables that use the Eigen::MatrixXd and Eigen::VectorXd. When all snakes are dead it's time to do a new generation, so I call a function that create this: std::vector<std::pair<std::unique_ptr<NeuralNetwork>, int>> paired_vector; (int for the points) I push_back my values like this:

for (int i{ 0 }; i < m_number_player; i++)
    {
        // make_pair to create a pair and std::move to move the content of each unique_ptr to the paired_vector
        paired_vector.push_back(std::make_pair(std::move(m_players[i]), m_points[i]));
    }

after, I sort my vector with the points of each snake:

std::sort(paired_vector.begin(), paired_vector.end(), [](const auto& a, const auto& b) { return a.second > b.second; });

and here is the problem:

// crossOver the bests
for (int i{ 10 }; i < m_number_player; i++)
    {
        int random1{ rand() % 11 };
        int random2{};
        do {
            random2 = rand() % 11;
        } while (random2 == random1);
        
        std::vector<Eigen::MatrixXd> value_returned = crossOverWeights(paired_vector[random2].first.get()->getWeigths(), paired_vector[random1].first.get()->getWeigths());
        paired_vector[i].first.get()->setWeigths(value_returned);

This part has to choose 2 random "snake" in the top 10. Then the function has to "mix" the weights of 2 best snakes to a bad snake. So I call the member function setWeights() to send the new weights with a function that returns the value. This function take 2 parameters:

std::vector<Eigen::MatrixXd> Game::crossOverWeights(const std::vector<Eigen::MatrixXd>& second, const std::vector<Eigen::MatrixXd>& first)

I have 4 functions like that: crossOverWeights, crossOverBiases, mutationWeights and mutationBiases that works exactly the same.

Inside the function :

std::vector<Eigen::MatrixXd> Game::crossOverWeights(const std::vector<Eigen::MatrixXd>& second, const std::vector<Eigen::MatrixXd>& first)
{
    std::vector<Eigen::MatrixXd> temp(second.size());
    // loop through all the weights
    for (int i{ 0 }; i < static_cast<int>(second.size()); i++)
    {
        // change the weights of the half first part
        if (i <= static_cast<int>(second.size() / 2))
            temp[i] = first[i];
        else // stay unchanged
            temp[i] = second[i];
    }   
    return temp;
}

The problem is: when I have 50 snakes the program crash at the 2nd generation. When I have 11 snakes, the program could crash at the fifth generation or something like that.

The error is "HEAP CORRUPTION DETECTED: After normal block...CRT detected that the application wrote to memory after end of heap buffer" So I think I reach the end of the vector or the Eigen::MatrixXd but how is it possible? When I set up the new weights I do that:

m_weights.clear();
    m_weights = new_weights;

Maybe someone knows the problem and can help me ? Thank you and don't hesitate to ask me for more details

PsyKozZ09
  • 21
  • 3
  • 3
    Heap corruption isn't a memory leak. Have you tried using a debugger? For us to debug for you you'll need to provide a [mre] – Alan Birtles Feb 19 '23 at 11:01
  • yes you're right, I'll try to do that I will edit my question with a better code. – PsyKozZ09 Feb 19 '23 at 11:04
  • 2
    You might find it helpful to know that if you use (for example) `temp.at()` instead of `temp[]`, the runtime will catch an accesses which are out of bounds (it will throw). – Paul Sanders Feb 19 '23 at 11:14
  • Thank you. I solved my problem but I am ashamed lol. The problem was in the for loop. When I tried to recreate my problem like Alan said, I remplace the second.size() by temp.size() and there was no problem anymore. It's weird because both should have the same size. – PsyKozZ09 Feb 19 '23 at 12:39
  • 2
    Just because it doesn't crash doesn't mean it's fixed, that's the joy of undefined behaviour seemingly irrelevant changes can "fix" problems. I'd recommend running your code with a sanitizer or using `at` as suggested above to find the actual problem – Alan Birtles Feb 19 '23 at 12:55
  • Ok I will do that and see where is the real error, thank you – PsyKozZ09 Feb 19 '23 at 13:34

0 Answers0