我遇到了一个奇怪的问题。我开发了一种遗传算法。
我有一个名为 IndividuoBinario
的类,在此类的构造器中具有私有string cromossomo;
,this->cromossomo = "1111111111111111";
包含 16 个元素,当像IndividuoBinario newIndividuo;
调用此类时工作正常,但是当我调用功能对时pair<IndividuoBinario, IndividuoBinario> newIndividuosCrossover;
会发生分段错误。但奇怪的是,当我放this->cromossomo = "111111111111111";
少于 16 个元素时,工作正常。
恢复:当通过功能对调用一个类并在字符串中放置超过 16 个元素时,会发生分段错误。
一些重要的代码:
void main() {
PopulacaoBinario pop;
pop = pop.rollet();
}
const PopulacaoBinario PopulacaoBinario::rollet() {
static mt19937 mt(time(NULL));
pair<IndividuoBinario, IndividuoBinario> newIndivuos;
static PopulacaoBinario newPop;
newPop.populacao.clear();
int var, valorDaRollet = 0, individuoParaCross[1] { 0 }, auxInsertIndv = 0;
double valorTotalFitness = 0.0, valorAcumuladoFitness = 0.0;
for (var = 0; var < this->qtdIndividuos; ++var) {
if (this->fitnessEscalonado)
valorTotalFitness += calculoFitnessEscalonado(this->populacao[var].getFitness());
else
valorTotalFitness += this->populacao[var].getFitness();
}
for (int loopNovosIndiv = 0; loopNovosIndiv < (this->qtdIndividuos * this->gap) / 2;
++loopNovosIndiv) {
for (int loop = 0; loop < 2; ++loop) {
static uniform_int_distribution<int> numeroRandom(0, 100);
valorDaRollet = numeroRandom(mt);
for (var = 0; var < this->qtdIndividuos - 1; ++var) {
if (this->fitnessEscalonado)
valorAcumuladoFitness += ((double) calculoFitnessEscalonado(
this->populacao[var].getFitness()) / valorTotalFitness) * 100;
else
valorAcumuladoFitness += ((double) this->populacao[var].getFitness()
/ valorTotalFitness) * 100;
if (valorDaRollet < valorAcumuladoFitness)
break;
}
valorAcumuladoFitness = 0;
individuoParaCross[loop] = var;
}
newIndivuos = crossoverUniforme(individuoParaCross[0], individuoParaCross[1]);
newPop.insertIndividuo(newIndivuos.first);
newPop.insertIndividuo(newIndivuos.second);
}
for (int count = newPop.getQtdIndividuos(); count < this->qtdIndividuos; ++count)
newPop.insertIndividuo(this->populacao[count]);
return newPop;
}
const pair<IndividuoBinario, IndividuoBinario> PopulacaoBinario::crossoverUniforme(int individuo1,
int individuo2) {
static mt19937 mt(time(NULL));
static uniform_int_distribution<int> bit(1, 99);
int var, a = bit(mt);
int qtdBits = this->populacao[individuo1].getCromossomo().size();
cout << "Before pair" << endl;
pair<IndividuoBinario, IndividuoBinario> newIndividuosCrossover;
cout << "not enough in this line" << endl;
IndividuoBinario newIndividuo1 = this->populacao[individuo1];
IndividuoBinario newIndividuo2 = this->populacao[individuo2];
if (this->chanceCrossover > a) {
string cromossomoNewInviduio1 = this->populacao[individuo1].getCromossomo();
string cromossomoNewInviduio2 = this->populacao[individuo2].getCromossomo();
for (int var = 0; var < this->populacao[individuo1].getCromossomo().size(); ++var) {
static uniform_int_distribution<int> numRandon(0, 1);
a = numRandon(mt);
if (a == 1) {
cromossomoNewInviduio1[var] = this->populacao[individuo2].getCromossomo()[var];
cromossomoNewInviduio2[var] = this->populacao[individuo1].getCromossomo()[var];
}
}
newIndividuo1.setCromossomo(cromossomoNewInviduio1);
newIndividuo2.setCromossomo(cromossomoNewInviduio2);
}
newIndividuosCrossover = make_pair(newIndividuo1, newIndividuo2);
return newIndividuosCrossover;
}
IndividuoBinario::IndividuoBinario() {
this->cromossomo = "1111111111111111"; //segmentation fault
this->cromossomo = "111111111111111"; //normal
cout << this->cromossomo << endl;
}
对不起,英语不好。
一个明显的问题是,在rollet()
中,定义
int individuoParaCross[1];
所以大小为 1 的 C 样式数组,并将其用作大小为 2 的数组操作系统
individuoParaCross[loop] = var; // with loop in [0,2[
// ...
newIndivuos = crossoverUniforme(individuoParaCross[0], individuoParaCross[1]);
代码来真正分析问题。请发布IndividuoBinario的类定义。
从您在此处发布的内容来看,我认为IndividuoBinario的复制构造函数或复制赋值存在问题。 克罗莫索莫似乎已损坏。
你不是碰巧使用 memcpy 来复制这些字符串吗?
顺便说一句,它不会为小字符串崩溃的原因可能是由于小字符串优化,其中值存储在对象中而不是堆上(请参阅 std::string 上下文中首字母缩略词 SSO 的含义)。但是您的字符串在任何情况下都已损坏。