Я каждый раз получаю ошибку сегментации в этом коде на разных строках. Переполнение стека

Я пишу программу генетического алгоритма. Я использую Linux (OS), c ++ (язык) и g ++ (компилятор).
Следующий код генерирует ошибку сегмента. Проблема в том, что иногда он запускается 50+ раз, а иногда нет. Кроме того, ошибка возникает в любой из строк назначения tmp [k] [p] или tmp [k + 1] [p]. Я что-то здесь упускаю?

int** GeneticAlgorythm::newGeneration( int** parents )
{
int** tmp = new int*[ population ];
int p = 0;

for( int k = 0; k < population; k += 2 )
{
tmp[ k ] = new int[ nGenes ];
tmp[ k + 1 ] = new int[ nGenes ];
setLikelihood( parents );

int parent1 = getParent( likelyhood );
int parent2 = getParent( likelyhood );

while( parent1 == parent2 )
{
parent2 = getParent( likelyhood );
}

for( p = 0; p < crossOverPoint; p++ )
{
tmp[ k ][ p ] = parents[ parent1 ][ p ];
tmp[ k + 1 ][ p ] = parents[ parent2 ][ p ];
}

for( p = crossOverPoint; p < nGenes; p++ )
{
tmp[ k ][ p ] = parents[ parent2 ][ p ];
tmp[ k + 1 ][ p ] = parents[ parent1 ][ p ];
}
}

currGeneration++;
return tmp;
}int GeneticAlgorythm::getParent( double* lh )
{
int randVal = rand( ) % 100;
int* choose = new int[ 100 ];
int counter = 0;

for( int k = 0; k < population; k++ )
{
for( int j = 0; j < (int)likelyhood[ k ]; j++ )
{
choose[ counter++ ] = j;
}
}

counter = choose[ randVal ];
delete[] choose;
return counter;
}

void GeneticAlgorythm::setLikelihood( int** pg )
{
multipleInverse = 0;
double one = 1.00;

for( int mi = 0; mi < population; mi++ )
{
multipleInverse  += one/checkFitness( pg[ mi ] );

}

for( int lh = 0; lh < population; lh++ )
{
likelyhood[ lh ] = round(((one/checkFitness( pg[ lh ] ))/multipleInverse) * 100);
}

}

Переменные значения:
население = 20; nGenes = 3; crossOverPoint = 1;

вероятность — это вероятность выбора родителя в зависимости от его уровня физической подготовки.
pg это родительские гены. [население] [nGenes].

Заранее спасибо.

1

Решение

Глядя на значения, которые вы указали, похоже, tmp все в порядке. Если строки, где вы видите, segfault являются

tmp[ k ][ p ] = parents[ parent1 ][ p ];
tmp[ k + 1 ][ p ] = parents[ parent2 ][ p ];

это должно быть из-за индексации в parents с [ parentN ][ p ],
Каковы размеры parents? Является getParent(…) гарантированно вернет действительный индекс в parents?

3

Другие решения

Ваш tmp[k+1] может выйти за пределы. Предполагать population = 3. Во втором цикле вы получили i=2 и вы делаете tmp[i+1] это tmp [3], и это выходит за пределы, что может привести к неопределенному поведению, потому что вы модифицируете память вне своего буферного пространства.

Если вы не уверены, что population является всегда четное число.

2

В этом коде:

int** tmp = new int* [population];

for (int k = 0; k < population; k += 2)
{
tmp[k] = new int[nGenes];
tmp[k + 1] = new int[nGenes];
...
}

когда population нечетное число, tmp[k + 1] в течение последней итерации доступ к массиву за его пределами, который производит неопределенное поведение. Вам посчастливилось наблюдать сбой вашей программы из-за ошибки сегментации, иначе эта ошибка могла бы остаться скрытой.

2
По вопросам рекламы [email protected]