释放和重新分配数组中的指针时内存泄漏

时间:2017-09-06 21:00:51

标签: c memory-management memory-leaks

我试图实施遗传算法来解决数独难题。我有一系列指向标本解决方案的指针(int *' s),因此我选择一个替换为新繁殖的标本 - 也就是说,释放指向的记忆,然后使其指向新标本。我的代码目前有内存泄漏,但我不知道为什么。这是我的主要内容:

int main(){

    //somewhere... is a memory leak.

    srand(time(NULL));

    int puzzle[] = {6,4,0,0,0,0,0,0,0,   
                    9,0,0,0,7,1,2,0,6,   
                    1,8,2,5,0,0,0,0,9,   
                    7,0,0,6,4,5,8,1,0,   
                    0,0,0,0,0,0,0,0,0,   
                    0,1,8,3,2,9,0,0,5,   
                    2,0,0,0,0,7,9,4,8,   
                    3,0,1,8,5,0,0,0,7,   
                    0,0,0,0,0,0,0,5,3};  

    int** population = generate_population();

    //ensure each specimen contains the puzzle-defined cells.
    for (int i=0; i<POP_SIZE; ++i){
        for (int j=0; j<81; ++j){
            if (puzzle[j] && population[i][j] != puzzle[j]){
            population[i][j] = puzzle[j];
            }
        }
    }

    //Create array of fitnesses for original population.
    int fitness[81];
    for (int i=0; i<POP_SIZE; ++i){
         fitness[i] = calculate_fitness(population[i]);
    }

    int average_fitness = 0;
    for (int i=0; i<POP_SIZE; ++i){
        printf("Specimen %i: Fitness: %i\n", i, fitness[i]);
        average_fitness += fitness[i];
    }
    printf("Average fitness: %f\n\n", (double)average_fitness/POP_SIZE);


    int* mother = NULL;
    int* father = NULL;
    int* child = NULL;

    int mother_index = 0;
    int father_index = 0;
    int exiled_index = 0;

    //Do some evolving
    for (int i=0; i<GENERATIONS; ++i){

        //choose parents.
        mother_index = choose_parent(fitness);
        father_index = choose_parent(fitness);

        if (mother_index == -1 || father_index == -1){
            //problems
            printf("CHOOSE_PARENT RETURNED -1!\n");
            exit(1);
        }

        mother = population[mother_index];
        father = population[father_index];

        //Breed mother and father, and mutate ensuring child conforms to puzzle definition.
        child = mutate(crossover(mother, father), puzzle);

        //Choose specimen to be removed, free the memory it takes up, and reallocate
        //the pointer with the new specimen.
        exiled_index = choose_exiled(fitness);
        free(population[exiled_index]);
        population[exiled_index] = child;

        //Update fitness array with new specimen's fitness.
        fitness[exiled_index] = calculate_fitness(population[exiled_index]);
    }


    //After evolution
    average_fitness = 0;
    for (int i=0; i<POP_SIZE; ++i){
        printf("Specimen %i: Fitness: %i\n", i, fitness[i]);
        average_fitness += fitness[i];
    }
    printf("Average fitness: %f\n\n", (double)average_fitness/POP_SIZE);

    return EXIT_SUCCESS;
}

在for循环的evolution中,crossover创建一个81个整数的新数组(变异然后存储在child中),之后我们释放存储在[exiled_index]中的任何内容,并将该指针重新分配给新的子节点。那么肯定,这个循环应该保持相同的内存使用量?嗯,它没有!我不知道记忆的去向。

以下是交叉和变异函数:

int* crossover(int* const mother, int* const father){
    int* child = malloc(sizeof(int)*81);
    for (int i=0; i<81; ++i){
        if (rand()%2){
            child[i] = mother[i];
        }
        else {
            child[i] = father[i];
        }
    }
    return child;
}

int* mutate(int* const child, int* puzzle){
    for (int i=0; i<81; ++i){
        if (child[i] == puzzle[i]){
            continue;
        }
        else if ((double)rand()/RAND_MAX < 0.125){
            child[i] = 1+rand()%9;
        }
    }
    return child;
}

如果需要,我可以提供更多代码,但我不认为需要其他代码来解释泄漏。

提前致谢。

0 个答案:

没有答案