使用删除时访问违规

Access violation when using delete

本文关键字:访问 删除      更新时间:2023-10-16

我有这两个类Bellow和一个名为" Creature"的第三类,该类别具有两个构造函数。

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 
};

两个构造函数是:

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 );
}

当我尝试删除使用第一个构造函数制造的生物时,就不会出现问题,但是使用第二个构造函数制造的生物给我一个毫无手感的例外。这是神经类别的破坏者:

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

这是我创建可以毫无问题的生物的创建方式:

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 );
}

这就是我创建删除时给出错误的生物的方式(最后6行):

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 );
    }
}

生物类:

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();
};

错误文本:evolution.exe中的0x6c7bad4a(msvcp100d.dll)的未手动异常

我将在问题所在的地方添加注释,但这是您的代码:

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 );
    }
}

由于您可能不会在0 -temp(生物)范围内的指示器上删除删除,因此您可能正在删除仍然存在的指针的指数,并且可能泄漏内存,因此测试该理论的最简单方法是为此:

for( int i = 0; i < temp; i++ )
{
    if( creatures[performances[i].second] != NULL )
    {
        // Second could be > temp
        delete creatures[performances[i].second]; 
        creatures[performances[i].second] = NULL;
    }
}

然后迭代并删除现在为空的索引。

首先,您的代码非常脏,我很喜欢您使用iterators来避免更多问题,也许您应该将shared_ptr用于"生物",而您无需删除它在破坏者中。

第二,您的主要问题是您正在尝试删除一个肮脏的指针,这是因为您以前曾在"自然选择"中删除它:

delete creatures[performances[i].second];