【问题标题】:Why does this introduce a memory leak?为什么这会引入内存泄漏?
【发布时间】:2016-04-14 17:43:58
【问题描述】:

我正在为 C 中的集合覆盖问题实现蚁群优化。在我的代码中,我发现了一个导致内存泄漏的函数。我很确定这个函数是内存泄漏的原因,因为我已经通过测试排除了其他函数。只是,我不明白为什么这个函数会导致内存泄漏。

为了理解这个函数,我将首先描述Ant 结构。 Ant 结构如下所示:

struct Ant {
    int* x;
    int* y;
    int fx;
    int** col_cover;
    int* ncol_cover;
    int un_rows;
    double* pheromone;
}

typedef struct Ant ant_t;

这个结构体中的指针(如xycol_cover等)使用malloc初始化并在程序结束时释放。现在,导致内存泄漏的函数如下:

void localSearch(ant_t* ant) {
    int improvement = 1;
    ant_t* antcpy = (ant_t*) malloc(sizeof(ant_t));
    initAnt(antcpy);
    copyAnt(ant, antcpy);
    while (improvement) {
        improvement = 0;
        for (int i = 0; i < inst->n; i++) {
            if (antcpy->x[i]) {
                removeSet(inst, antcpy, i);
                while (!isSolution(antcpy)) {
                    constructSolution(antcpy);
                }
                if (antcpy->fx < ant->fx) {
                    copyAnt(antcpy, ant);
                    improvement = 1;
                    eliminate(ant);
                } else {
                    copyAnt(ant, antcpy);
                }
            }
        }
    }
    free((void*) antcpy);
}

首先,我使用initAnt 函数创建Ant 结构(antcpy) 的另一个实例。 copyAnt 函数将一个 Ant 结构深拷贝到另一个 Ant 结构。我做深拷贝的原因如下;我正在更改antcpy,然后将其与ant 进行比较。如果结果更好 (antcpy-&gt;fx &lt; ant-&gt;fx),ant 将替换为 antcpy。如果结果更糟,antcpy 将恢复为 ant 的值。

这些功能如下:

void initAnt(ant_t* ant) {
    ant->x = (int*) malloc(inst->n * sizeof(int));
    ant->y = (int*) malloc(inst->m * sizeof(int));
    ant->col_cover = (int**) malloc(inst->m * sizeof(int*));
    ant->ncol_cover = (int*) malloc(inst->m * sizeof(int));
    ant->pheromone = (double*) malloc(inst->n * sizeof(double));
    for (int i = 0; i < inst->m; i++) {
        ant->col_cover[i] = (int*) malloc(inst->ncol[i] * sizeof(int));
    }
}

void copyAnt(ant_t* from, ant_t* to) {
    to->fx = from->fx;
    to->un_rows = from->un_rows;
    for (int i = 0; i < inst->n; i++) {
        to->x[i] = from->x[i];
        to->pheromone[i] = from->pheromone[i];
    }
    for (int i = 0; i < inst->m; i++) {
        to->y[i] = from->y[i];
        to->ncol_cover[i] = from->ncol_cover[i];
        for (int j = 0; j < inst->ncol[i]; j++) {
            to->col_cover[i][j] = from->col_cover[i][j];
        }
    }
}

我真的不明白为什么这段代码会导致内存泄漏,因为我在localSearch 函数的末尾释放了antcpy。那么,为什么这段代码会引入内存泄漏,我该如何解决呢?

【问题讨论】:

  • 您不需要 freemalloc 的演员表
  • @EdHeal 把它们留在那儿有害吗?
  • 你在哪里释放initAnt中分配的内存?我想 mymalloc 做了某种分配......
  • @JNevens - 你只是不需要它们
  • @AdrianRoman mymalloc 只是 malloc 的包装。 initAnt中分配的内存不是在localSearch函数结束时通过释放antcpy来释放的吗?

标签: c struct memory-leaks


【解决方案1】:

你必须实现一个函数freeAnt,在free((void*) antcpy);之前释放所有在initAnt中分配的内存。

void freeAnt(ant_t* ant) {
    for (int i = 0; i < inst->m; i++) {
        free(ant->col_cover[i]);
    }
    free(ant->pheromone);
    free(ant->ncol_cover);
    free(ant->col_cover);
    free(ant->y);
    free(ant->x);
}

【讨论】:

  • 所以基本上是一个为Ant 结构的每个元素执行free(antcpy-&gt;x) 的函数?那么col_cover 呢,因为它是一个数组数组。我是否还需要释放 col_cover 内的每个数组,还是 free(antcpy-&gt;col_cover) 会处理这个问题?
  • 对于每个malloc,都应该有一个对应的free,所以不,free(antcpy-&gt;col_cover)是不够的。
  • 是的,每个指向已分配内存的指针。这包括 col_cover。首先,您只在 free(ant-&gt;col_cover); 之后执行 for (int i = 0; i &lt; inst-&gt;m; i++) { free(ant-&gt;col_cover[i]); }free(ant) 排在最后。也就是说,与分配时相反。
  • 总的来说(当然也有例外)我认为将free 内存作为malloced 的镜像是一个很好的做法。但是是的,每个malloc 都应该有一个对应的free(同样可以有exceptions
猜你喜欢
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 2010-10-11
  • 2011-10-21
  • 2021-08-15
相关资源
最近更新 更多