C-可能的内存泄漏?

时间:2011-10-10 17:36:10

标签: c data-structures multidimensional-array struct free

我觉得我的一段代码会导致内存泄漏。我有一个带有两个二维数组的数据结构,一个包含int,另一个包含动态分配对象(sprite)的指针。数据结构是tilemap,int是每个位置的数字索引,从文件中读取。我把那个索引称为“瓷砖”。这说明了它是什么类型的瓷砖,出于行为目的(即玩家对水的反应不同于对泥土或冰的反应)。对象是在各自位置绘制的精灵。该指数被称为“图像”。该索引告诉tilemap在该位置绘制的精灵。

typedef struct
{
    int** tiles;
    sprite*** images;
    int w, h;
} tilemap;

我有一个创建新tilemap的函数,初始化它并返回它。

tilemap* new_tilemap(int w, int h, const char* filename)
{
    tilemap* tm = malloc(sizeof(tilemap));
    tm->w = w;
    tm->h = h;

    /*allocate memory space for the tiles index*/
    tm->tiles = malloc(sizeof(int) * h);
    int i, j;
    for (i = 0; i < h; ++i)
    {
        tm->tiles[i] = malloc(sizeof(int) * w);
    }

    /*fill the index with the appropriate data from a file*/
    FILE* file = fopen (filename, "rb");
    if (file == NULL)
    {
        printf("Failed to open map %s\n", filename);
    }

    for (j = 0; j < h; ++j)
    {
        for (i = 0; i < w; ++i)
        {
            fscanf(file, "%d", &(tm->tiles[j][i]));
        }
    }
    fclose(file);

    /*allocate space for the images*/
    tm->images = malloc(sizeof(sprite*) * h);
    for (i = 0; i < h; ++i)
    {
        tm->images[i] = malloc(sizeof(sprite*) * w);
    }

    /*load images based on what type of tile is at that position*/
    for (j = 0; j < h; ++j)
    {
        for (i = 0; i < w; ++i)
        {
            switch (tm->tiles[j][i])
            {
                case 0:
                tm->images[j][i] = new_sprite_file("dat/tiles/0.bmp", 1);
                break;
                case 1:
                tm->images[j][i] = new_sprite_file("dat/tiles/1.bmp", 2);
                break;
            }
            tm->images[j][i]->x = i*tm->images[j][i]->w;
            tm->images[j][i]->y = j*tm->images[j][i]->h;
        }
    }
    return tm;
}

然后,为了释放tilemap及其所有结构,我有这个功能:

void free_tilemap(tilemap* tm)
{
    /*loop through and free each of the images in the array*/
    int i, j;
    for (j = 0; j < tm->h; ++j)
    {
        for (i = 0; i < tm->w; ++i)
        {
            free(tm->images[j][i]);
         }
    }
    /*free the actual array*/
    free(tm->images);
    /*free the tile array?*/
    free(tm->tiles);
    /*free the entire tilemap structure*/
    free(tm);
}

但是,我觉得它没有释放我分配的所有内存,因为我在磁贴上使用了malloc两次,但只使用了一次。我不知道这是否是一个问题,因为它们是整数,但我认为我可能需要遍历tiles数组,释放每一行,然后循环并释放每一列(包含行),与分配的方式相同。这是需要做什么,还是我只是无知和/或偏执?与图像数组相同。另外,请随意指出我的代码中的其他缺陷,因为我知道我不是最好的程序员。

2 个答案:

答案 0 :(得分:3)

当然,你应该在空闲时镜像malloc

for (i = 0; i < h; ++i)
{
    tm->tiles[i] = malloc(sizeof(int) * w);
}

/* Inside free_tilemap. */
for (i = 0; i < h; ++i)
{
    free(tm->tiles[i]);
}
free(tm->tiles);

与其他for非常相似的其他tiles也是如此。仅仅tiles[0..h]释放不会自动释放{{1}}级联。

答案 1 :(得分:2)

快速查看代码,我会说你确实错过了瓷砖上的免费代码。我建议使用内存分析器自行查找。例如。 http://www.cprogramming.com/debugging/valgrind.html 这将为您提供已分配内存的良好概览,以及程序退出时可能的内存泄漏。