-6

I encountered a strange problem. I developing a genetic algorithm.

I have a class named IndividuoBinario with private string cromossomo; in construtor of this class put this->cromossomo = "1111111111111111"; with 16 elements, when call a this class like IndividuoBinario newIndividuo; work fine, BUT when i call with fuction pair like pair<IndividuoBinario, IndividuoBinario> newIndividuosCrossover; happen a segmentation fault. But the strange thing is that when i put this->cromossomo = "111111111111111"; with less then 16 elements work fine.

Resume: when call a class by fuction pair and put more then 16 elements in string happen a segmentation fault.

Some important codes:

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;
}

Sorry by the bad english.

Dekonunes
  • 523
  • 5
  • 10

2 Answers2

1

An obvious problem is that you, in rollet(), define

int individuoParaCross[1];

so a C-style array of size 1, and use it as an array os size 2

individuoParaCross[loop] = var;  // with loop in [0,2[
// ...   
newIndivuos = crossoverUniforme(individuoParaCross[0], individuoParaCross[1]);
max66
  • 60,491
  • 9
  • 65
  • 95
0

There's not enough code to really analyse the problem. Please post the class definition for IndividuoBinario.

From what you posted here, I would think there's a problem with the copy constructor or copy assignment for IndividuoBinario. cromossomo seems to be corrupted.

You don't happen to use memcpy to copy those strings?

Btw, the reason it doesn't crash for small strings may be due to small string optimisation, where the value is stored in the object instead of on the heap (see Meaning of acronym SSO in the context of std::string). But your string is corrupted in any case.

Community
  • 1
  • 1
Jan
  • 1,749
  • 11
  • 24