内存泄漏,同时分配二维游戏领域

时间:2015-03-24 16:09:59

标签: c

我是使用Valgrind的新手并且在调试代码时遇到了问题,因为除了我假设标记行上的内存泄漏之外它还可以工作。我在这里分配错误的尺寸吗?

Field *createField(unsigned int xsize, unsigned int ysize) {
    /* Alright! Let's start off by assigning an new field that we can return.*/

unsigned int i, j;
    Field *returnField;
    returnField = malloc(sizeof(Field));
    if(returnField == NULL) {
        return NULL;
    }

    returnField->xsize = xsize;
    returnField->ysize = ysize;
    returnField->cells = malloc(ysize * sizeof(State *)); // memory leaks?!
    if(returnField->cells == NULL) {
        free(returnField);
        return NULL;
    }
    /* Alright, now we have the y dimension pointer allocated. It's time
     * to move on to the x dimension*/

    for (j = 0; j < ysize; j++) {
        returnField->cells[j] = malloc(xsize * sizeof(State));
        if (returnField->cells[j] == NULL) {
            for (i = 0; i < j; i++) {
                free(returnField->cells[i]);
            }
            free(returnField);
            return NULL;
        }
        for (i = 0; i < xsize; i++) {
            returnField->cells[j][i] = DEAD;
        }
    }

    return returnField; 
}
/* Free memory allocated for field <f>.
 */
void releaseField(Field *f)
{
    unsigned int j;
    for (j = 0; j < f->ysize; j++) {

        free(f->cells[j]);
    }
    free(f);
}

下面是包含结构的标题:

typedef enum {
    DEAD,
    ALIVE
} State;

typedef struct {
    unsigned int xsize, ysize;
    State **cells;
} Field;

2 个答案:

答案 0 :(得分:3)

您可以分配内存来保存单元格指针:

returnField->cells = malloc(ysize * sizeof(State *));

但你永远不会释放那段记忆。你释放单个单元格,但从不释放单元格指针:

    if (returnField->cells[j] == NULL) {
        for (i = 0; i < j; i++) {
            free(returnField->cells[i]);
        }
        free(returnField->cells);
        // ^^ This was missing
        free(returnField);
        return NULL;
    }

releaseField()实施中出现同样的问题。我甚至建议将强大反对部分分配:

/* Free memory allocated for field <f>.
 */
void releaseField(Field *f)
{
    unsigned int j;
    if (f != NULL) {
       if (f->cells != NULL) {
           for (j = 0; j < f->ysize; j++) {
               free(f->cells[j]);
           }
       }
       // free cell pointer array memory, too
       free(f->cells);
       free(f);
    }
}

同样用

替换returnField->cells = malloc(ysize * sizeof(State *));
returnField->cells = calloc(ysize, sizeof(State *));

在分配returnField结构本身时执行相同的操作,您甚至可以将releaseField()用于部分分配的字段,从而避免代码重复:

returnField = calloc(1, sizeof(Field));

这样,即使您只有部分分配的字段结构,也应该能够简单地调用releaseField()

答案 1 :(得分:2)

这可能不是真正的问题,但您没有释放在此块中为cells分配的内存。

    if (returnField->cells[j] == NULL) {
        for (i = 0; i < j; i++) {
            free(returnField->cells[i]);
        }

        // Need to deallocate returnField->cells
        // Add the following line.
        free(returnField->cells);

        free(returnField);
        return NULL;
    }