我有这两个类以及第三个名为“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::~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)的未处理异常:0xC0000005:访问冲突读取位置0xfeeefef2。
答案 0 :(得分:0)
首先,你的代码真的很脏,我很高兴你使用iterators
来避免更多的问题,也许你应该使用shared_ptr
作为“生物”,这样你就不需要删除它在析构函数中。
其次,你的主要问题是你试图删除一个脏指针,这是因为你之前在“NaturalSelection”中删除了它:
delete creatures[performances[i].second];
答案 1 :(得分:0)
我会在问题所在地添加注释,但这是您的代码:
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(生物)范围内的指针上调用delete,你可能正在删除仍然存在的指针索引,并且可能泄漏内存。测试这个理论的最简单方法是这样做:
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;
}
}
然后迭代并删除现在为空的索引。