我每次都在不同的行上对此代码进行分段错误。 C ++

时间:2013-05-02 20:54:41

标签: c++ segmentation-fault genetic-algorithm

我正在写一个遗传算法程序。我使用Linux(OS),c ++(语言)和g ++(编译器)。 以下代码生成seg错误。问题是它有时会运行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]。

提前致谢。

3 个答案:

答案 0 :(得分:3)

查看您提供的值,看起来您对tmp的索引是正常的。如果您看到段错误的行是

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

它必须是因为parents[ parentN ][ p ]的索引。 parents的维度是多少? getParent(…)是否保证将有效索引返回parents

答案 1 :(得分:2)

你的tmp[k+1]可能超出范围。假设population = 3.在你的第二次循环运行中你得到了i=2而你做了tmp[i+1]这是tmp [3]并且超出界限会导致未定义的行为,因为你是修改缓冲区空间之外的内存。

除非您确定population 总是是偶数。

答案 2 :(得分: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]会从其边界中访问数组,从而产生 未定义的行为 。您很幸运能够观察到由于分段错误而导致程序崩溃,否则此错误可能会隐藏起来。