访问第一个元素时出现 C++ 向量分段错误
C++ vector segmentation error when accessing the first element
我一直很难解决这个错误,因为我已尽我所能修复它,但无济于事。
我正在为我的 C++ class 构建一个遗传算法,我必须将很多个体存储在某种容器中,所以我选择制作一个名为 class 的自定义容器"GenePool" 保存 "IndivPtr" 的实例(这是指向 "Individual" 的 typedef 智能指针)。
这些个体存储在它的内部向量中,我重载了下标运算符 ([]) 来访问它的元素。
但是,我的程序几乎没有运行,因为在用元素填充向量之后,当试图从向量中访问第一个元素时,它总是会导致分段错误,并抛出 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;
}
}
首先,在 pushBackIndiv 中,您应该为不是 LangermannPoint 或 CurveParams 的错误情况添加一个 else。看起来问题不在这里,但你应该添加它会帮助你。
其次,在 operator[](int index) 中,在访问元素之前检查请求的索引是否不会超出范围。您可以通过 individualList.size().
进行比较来检查这一点
同时调用 size() 来查看列表中是否确实有元素。
好吧,事实证明,我一直收到此错误的真正原因是因为我犯了一个愚蠢的错误:我忘记了初始化人口的大小,所以它从来没有在向量中添加元素我以为是。
但值得庆幸的是,通过调查这个错误以及如何制作抽象数据类型的向量,我了解了所有关于分段错误的知识:)
我一直很难解决这个错误,因为我已尽我所能修复它,但无济于事。
我正在为我的 C++ class 构建一个遗传算法,我必须将很多个体存储在某种容器中,所以我选择制作一个名为 class 的自定义容器"GenePool" 保存 "IndivPtr" 的实例(这是指向 "Individual" 的 typedef 智能指针)。
这些个体存储在它的内部向量中,我重载了下标运算符 ([]) 来访问它的元素。
但是,我的程序几乎没有运行,因为在用元素填充向量之后,当试图从向量中访问第一个元素时,它总是会导致分段错误,并抛出 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;
}
}
首先,在 pushBackIndiv 中,您应该为不是 LangermannPoint 或 CurveParams 的错误情况添加一个 else。看起来问题不在这里,但你应该添加它会帮助你。
其次,在 operator[](int index) 中,在访问元素之前检查请求的索引是否不会超出范围。您可以通过 individualList.size().
进行比较来检查这一点同时调用 size() 来查看列表中是否确实有元素。
好吧,事实证明,我一直收到此错误的真正原因是因为我犯了一个愚蠢的错误:我忘记了初始化人口的大小,所以它从来没有在向量中添加元素我以为是。
但值得庆幸的是,通过调查这个错误以及如何制作抽象数据类型的向量,我了解了所有关于分段错误的知识:)