0

私はまだ遺伝的アルゴリズムを機能させようとしています(昨日、メモリ割り当てに問題があり、その結果、メモリを解放しようとするとひどいエラーが発生しました)が、今日はこのコードを持っています

while (iCurrentGen <= data->m_iMaxGenerations)
{
    arrfSelectedChromosomes = selection(&data[0], szChromosomes);
    iSelectedLen = order_descending_grid(arrfSelectedChromosomes);
    szAuxGen = crossover(&data[0], arrfSelectedChromosomes, szChromosomes, iSelectedLen);
    //szChromosomes is what I need to free after that call returns
    free_generation(&data[0], szChromosomes);//Code Explotion
    szChromosomes = szAuxGen;
    szAuxGen = NULL;
    ++iCurrentGen;
}

free_generation()関数呼び出しの前にその内容を確認していたところ、下の図のようなものでした。

(変数の最初の 4 つの値)

変数の最初の 4 つの値

しかし、free_generation()関数内では、以下に示すように、同じ変数がその値の一部を失います (具体的には、for ループ インデックスであるi値 2 を取る場合)。i

(関数内の変数値)

関数内の変数値

以下に free_generation コードを投稿します。

void free_generation(struct INPUT_DATA* d, char** szChromosomes)
{
    int i;

    for (i = 0; i < d->m_iPopulationSize; ++i)
    {
        free(szChromosomes[i]);
    }

    free(szChromosomes);
    szChromosomes = NULL;
}

の定義szChromosomesは次のとおりです。

char** szChromosomes = (char**)malloc(d->m_iPopulationSize * sizeof(char*));

srand(time(NULL));
for (i = 0; i < d->m_iPopulationSize; ++i)
{
    szChromosomes[i] = (char*)malloc((d->m_iBitsPChromosome + 1) * sizeof(char));
    for (j = 0; j < d->m_iBitsPChromosome; ++j)
    {
        szChromosomes[i][j] = rand_1_0(0.0, 1.0) == 1? '1' : '0';
    }
    szChromosomes[i][j] = '\0';
}

この値の損失は、一番上に投稿された while ループの 2 回目の繰り返しの後にのみ発生することを明確にする必要があります。つまり、最初の実行ではすべてが完全に機能しますが、この反復の後、2 回目は上記のように動作します。

編集:

ループ制御変数のインクリメントを含めるのを忘れていました (指摘してくれてありがとう! いいえ、グローバル xD ではありません)。クロスオーバーコードの一部を含めています:

    char** crossover(struct INPUT_DATA* d, float** arrfSelectedChromosomes, char** arrszChromosomes, int iChromosomesInGrid)
{
    int i;
    int iTIndex = 0, iRPos = 0;
    char* szFirstChromosome = NULL;
    char* szSecondChromosome = NULL;
    char* szFirstNewChrom = (char*)malloc((d->m_iBitsPChromosome + 1) * sizeof(char));
    char* szSecondNewChrom = (char*)malloc((d->m_iBitsPChromosome + 1) * sizeof(char));

    char** arrszNewPop = (char**)malloc(d->m_iPopulationSize * sizeof(char*));

    int iSplitPoint = (int)(d->m_iBitsPChromosome / 4);

    float fCrossOverProb = CROSSOVER_PROBABILITY; 

    srand(time(NULL));
    for (i = 0; i < d->m_iPopulationSize; i += 2)
    {
        iRPos = rand() % iChromosomesInGrid;
        iTIndex = (int)arrfSelectedChromosomes[iRPos][0];
        szFirstChromosome = arrszChromosomes[iTIndex];
        iRPos =  rand() % iChromosomesInGrid;
        iTIndex = (int)arrfSelectedChromosomes[iRPos][0];
        szSecondChromosome = arrszChromosomes[iTIndex];

        if (is_same_chromosome(szFirstChromosome, szSecondChromosome))
        {
            i -= 2;
            continue;
        }

        if (fCrossOverProb < CROSSOVER_PROBABILITY)
        {
            //if probability is lower than the defined prob. we keep both chromosomes
            strcpy(szFirstNewChrom, szFirstChromosome);
            strcpy(szSecondNewChrom, szSecondChromosome);
        }
        else
        {

            strcpy(szFirstNewChrom, szFirstChromosome);
            szFirstNewChrom[iSplitPoint] = '\0';
            strcat(szFirstNewChrom, &szSecondChromosome[iSplitPoint]);

            //Para crear el segundo hijo se realiza una operacion similar
            strcpy(szSecondNewChrom, szSecondChromosome);
            szSecondNewChrom[iSplitPoint] = '\0';
            strcat(szSecondNewChrom, &szFirstChromosome[iSplitPoint]);
        }

        arrszNewPop[i] = szFirstNewChrom;
        arrszNewPop[i + 1] = szSecondNewChrom;
    }

    return arrszNewPop;
}
4

1 に答える 1

1

コメントを回答としてマークする機能のリクエストは引き続き拒否されるため、上記のソリューションをここにコピーします。

nm あなたは男です!どうもありがとう..それは重複したポインタの問題であり、クロスオーバー関数のメモリ割り当てが間違っていたためでした。関数の先頭で szFirstNewChrom と szSecondNewChrom にメモリを割り当てていましたが、そのメモリは 30 個の異なる文字列に使用されました。そのひどい間違いのために、 free_generation 関数は、以前に解放されたポインターを解放しようとしていたため、失敗し続けました。皆さん、ありがとうございました!– ホルヘ・セスペデス

于 2014-06-03T11:40:08.790 に答える