2013-02-27 2 views
1

Я пишу код для генетического алгоритма, и я застреваю в точке, где я не могу освободить неиспользуемую память. Это мой основной (код):Ошибка при освобождении двойной указатель в C

szChromosomes = initial_population(&data[0]); 
while (iCurrentGen <= data->m_iMaxGenerations) 
{ 
    arrfSelectedChromosomes = selection(&data[0], szChromosomes); 
    iSelectedLen = order_descending_grid(arrfSelectedChromosomes); 
    szAuxGen = crossover(&data[0], arrfSelectedChromosomes, szChromosomes); 
    free_generation(&data[0], szChromosomes);//Error line 
    szChromosomes = szAuxGen; 
    szAuxGen = NULL; 
} 

initial_population (& данные [0]) создает массив szChromosomes (который я пытаюсь освободить позже), как это:

char** initial_population(struct INPUT_DATA* d) 
{ 
int i, j = 0; 
float fMember = 0.0; 
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 * 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'; 
} 

return szChromosomes; 

}

Когда я вызываю функцию free_generation, выполняется цикл For ниже:

int i; 

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

free(szChromosomes); 
szChromosomes = NULL; 

Wh первый вызов бесплатно (szCromosomes [i]); происходит, я получаю следующую ошибку:

ОПРЕДЕЛЕННАЯ КОРРУПЦИЯ HEAP: после нормального блока (# 99). CRT обнаружил, что приложение записано в память после завершения буфера кучи.

+0

Попробуйте '(char *) malloc (d-> m_iBitsPChromosome + 1);'. В конце вам нужен дополнительный символ для '' \ 0''. Умножение на 'sizeof (char)' избыточно, поскольку «char», определяемый стандартом, имеет размер 1 байт. –

ответ

2
char** initial_population(struct INPUT_DATA* d) 
{ 
int i, j = 0; 
float fMember = 0.0; 
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 * 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'; 
} 

return szChromosomes; 

Вы вставить '\ 0' в конце каждой строки szChromosomes [я], но только использовать таНос с длиной d-> m_iBitsPChromosome

Итак, вы пытаетесь записать слишком далеко в памяти. Чтобы изменить это, просто измените ваш второй malloc на:

szChromosomes[i] = (char*)malloc((d->m_iBitsPChromosome + 1) * sizeof(char)); 
+0

В этом была проблема с дополнительным байтом для символа \ 0! Не могу поверить, что я так скучал по этому поводу! Спасибо вам, ребята! –

1
szChromosomes[i][j] = '\0'; 

Эта строка записывает в память, которой у вас нет.

Для примера. взять этот пример

char * p; 
p = malloc(2); 
p[0] = 'a'; 
p[1] = 'b'; 

Вы не должны делать

p[2] = '\0' 

после этого, потому что вы выделили только 2 байта, но вы пишете 3 байта.

Вы можете исправить это 2 способа

  1. ли вам нужен '\ 0'. Если вы не собираетесь использовать одну из функций от <string.h>, которая ожидает, что «\ 0» проверяет конец, вам нужно завершить его с помощью «\ 0». В вашем собственном коде, который пересекает массив, вы можете перемещаться с использованием цикла for, который заканчивается на ctr < d->m_iBitsPChromosome.

  2. Или вы можете выделить malloc(d->m_iBitsPChromosome + 1)

Смежные вопросы