2013-02-28 18 views
0

我仍然在試圖讓我的遺傳算法工作,但今天我有這樣一段代碼釋放內存時奇怪的C錯誤?

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()函數調用之前它的內容,它是像下面的圖片:

(可變前四個值)

Variable first four values

free_generation()函數內部中,相同的變量失去它的一些值(具體而言,當i取值2,i是for循環索引),如下所示:

(在函數內部變量值)

Variable values inside the function

我發佈以下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循環的第二次迭代發佈在頂部之後。我的意思是在第一次運行時一切都完美,但在迭代之後,第二次運行如上所述。

編輯:

我忘了,包括循環控制變量的增量(感謝指出了這一點,並沒有,它不是全局的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; 
} 
+1

如果您在Linux或MacOS/X下運行,請嘗試安裝valgrind並在其下運行程序。它可能會告訴你事情出錯的地方。 – 2013-02-28 17:35:33

+1

您的染色體數組包含重複的指針值。一旦你對同一個指針使用了'free'兩次,所有的地獄都會崩潰。順便說一句,這發生在迭代3(i == 2)。您需要跟蹤這些重複值如何在數組中結束。 – 2013-02-28 17:41:50

+0

我在windows下Jeremy ..可以重複的指針值是因爲調用strcat像這樣: strcpy(szFirstNewChrom,szFirstChromosome); szFirstNewChrom [iSplitPoint] ='\ 0'; strcat(szFirstNewChrom,&szSecondChromosome [iSplitPoint]); iSplitPoint是0到31之間的整數。我創建了一個與兩條染色體串聯的新染色體。 szFirstNewChrom在使用前分配33個字節 – 2013-02-28 17:53:51

回答

1

由於功能要求mark a comment as an answer繼續下降,我在這裏複製上面的解決方案。

n.m你是男人!非常感謝。這是一個重複指針的問題,這是由於交叉函數中的內存分配錯誤。我在函數的開頭爲szFirstNewChrom和szSecondNewChrom分配內存,但是這個內存被用於30個不同的字符串。由於那個可怕的錯誤,free_generation函數一直在失敗,因爲它試圖釋放一個先前釋放的指針。謝謝你們! - Jorge Cespedes