当字符串有16个或更多元素时,分段错误

时间:2016-06-05 03:56:04

标签: c++ string segmentation-fault bits

我遇到了一个奇怪的问题。我开发了一种遗传算法。

我在这个类的construtor中有一个名为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;
}

对不好的英语抱歉。

2 个答案:

答案 0 :(得分:1)

一个明显的问题是,您在rollet()中定义了

int individuoParaCross[1];

这是一个大小为1的C风格数组,并将其用作数组大小为2

individuoParaCross[loop] = var;  // with loop in [0,2[
// ...   
newIndivuos = crossoverUniforme(individuoParaCross[0], individuoParaCross[1]);

答案 1 :(得分:0)

没有足够的代码来真正分析问题。请发布IndividuoBinario的课程定义。

根据您在此处发布的内容,我认为IndividualuoBinario的复制构造函数或副本分配存在问题。 cromossomo似乎已被腐蚀。

您是不是碰巧使用memcpy来复制这些字符串?

顺便说一下,小字符串不崩溃的原因可能是由于小字符串优化,其中值存储在对象而不是堆中(参见Meaning of acronym SSO in the context of std::string)。但是你的字符串在任何情况下都会被破坏。