我一直在努力解决这个错误,因为我已尽力解决这个问题但无济于事。
我为我的C ++类构建遗传算法,我必须将很多个人存储在某种容器中,所以我选择创建一个名为" GenePool"的自定义容器类。持有" IndivPtr"的实例(这是一个typedef智能指针,指向"个人")。
这些个体存储在其内部向量中,我重载了下标运算符([])以访问其元素。
然而,我的程序几乎没有运行,因为在使用元素填充向量之后,它总是在尝试从向量访问FIRST元素时导致分段错误,并且它会抛出std :: out_of_range异常!
我想知道在这种情况下如何从我的向量访问元素而不会导致这样的错误。
以下是GenePool的代码:
#include "GenePool.h"
#include "Controller.h"
#include <algorithm>
GenePool::GenePool()
{
// Default empty constructor
individualList.reserve(10000);
}
GenePool::~GenePool()
{
//deleteAll();
}
void GenePool::sortPool()
{
// Sort the vector from greatest to least using GreatertThanSort
// The third parameter is the address of the GreaterThanSort's greater than function for a GreaterThanSort for Individuals
std::sort(individualList.begin(), individualList.end(), &GreaterThanSort::greaterThan);
}
Individual& GenePool::operator[](int index)
{
// Put exception handling here somewhere (a throw statement)
return *individualList.at(index);
}
// Get an individual from the list between index 0 and index size - 1
Individual& GenePool::getRandIndiv()
{
return this->operator[](Controller::getRandNumInRange(0, this->size() - 1));
}
void GenePool::pushBackIndiv(const IndivPtr& indiv)
{
individualList.push_back(indiv);
}
void GenePool::pushBackIndiv(Individual& indiv)
{
Individual * p2Indiv = &indiv;
if(LangermannPoint * pIndivL = dynamic_cast<LangermannPoint*>(p2Indiv))
{
IndivPtr pL(new LangermannPoint(*pIndivL));
individualList.push_back(pL);
}
else if(CurveParams * pIndivC = dynamic_cast<CurveParams*>(p2Indiv))
{
IndivPtr pC(new CurveParams(*pIndivC));
individualList.push_back(pC);
}
}
int GenePool::size() const
{
return individualList.size();
}
void GenePool::clear()
{
if(!individualList.empty())
{
individualList.clear();
}
}
void GenePool::addContentsOf(GenePool& other)
{
for(int i = 0; i < other.size(); ++i)
{
pushBackIndiv(other[i]);
}
}
在调用此下标之前,向量将被填充:
// Initialize a population of individuals with randomly generated parameters.
if(getProblemType() == Controller::OPTIMIZATION)
{
for(int i = 0; i < getInitPopSize(); ++i)
{
population.pushBackIndiv(IndivPtr(new LangermannPoint(getRandFloatInRange(0.0f, LangermannPoint::POINT_BOUND),
getRandFloatInRange(0.0f, LangermannPoint::POINT_BOUND))));
}
}
else
{
for(int i = 0; i < getInitPopSize(); ++i)
{
population.pushBackIndiv(IndivPtr(new CurveParams(getRandFloatInRange(-CurveParams::PARAM_BOUND, CurveParams::PARAM_BOUND),
getRandFloatInRange(-CurveParams::PARAM_BOUND, CurveParams::PARAM_BOUND),
getRandFloatInRange(-CurveParams::PARAM_BOUND, CurveParams::PARAM_BOUND),
getRandFloatInRange(-CurveParams::PARAM_BOUND, CurveParams::PARAM_BOUND))));
}
}
以下是对始终崩溃的下标运算符的调用:
bool Controller::terminationCondition()
{
population.sortPool();
// After sorting, the first is the fittest
if(generationCount <= 1)
{
setSolution(population[0]);
return false;
}
else if(getSolution() < population[0] && generationCount < MAX_GEN_COUNT)
{
setSolution(population[0]);
return false;
}
else
{
return true;
}
}
答案 0 :(得分:1)
首先,在pushBackIndiv中,你应该为错误的情况添加一个else,而不是LangermannPoint或CurveParams。似乎问题不在这里,但你应该补充说它会帮助你。
其次,在operator [](int index)中,在访问元素之前检查请求的索引是否不会超出范围。您可以与individualList.size()进行比较。
同时调用size()以查看列表中是否包含元素。