C- возможная утечка памяти? - PullRequest
       23

C- возможная утечка памяти?

3 голосов
/ 10 октября 2011

Я чувствую, что фрагмент кода, который у меня есть, вызовет утечку памяти.У меня есть структура данных с двумя двумерными массивами, один из которых содержит целые, а другой содержит указатели на динамически размещаемые объекты (спрайты).Структура данных представляет собой карту листов, а целые числа представляют собой числовые индексы каждого местоположения, которые считываются из файла.Я называю этот индекс «плитки».Это говорит о том, что это за плитка, для поведенческих целей (т. Е. Игрок по-разному реагирует на воду, чем на грязь или лед).Объекты - это спрайты для рисования в соответствующих местах.Этот индекс известен как «изображения».Этот индекс сообщает карте тайлов, какой спрайт рисовать в этой позиции.

typedef struct
{
    int** tiles;
    sprite*** images;
    int w, h;
} 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;
}

Затем,чтобы освободить карту тайла и все его структуры, у меня есть эта функция:

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 дважды на тайлах, нотолько один разЯ не знаю, если это проблема, хотя, учитывая, что они являются целочисленными, но я думаю, что мне, возможно, придется циклически проходить по массиву плиток, освобождать каждую строку, а затем проходить и освобождать каждый столбец (содержащий строки), втак же, как это было выделено.Это то, что нужно сделать, или я просто невежественен и / или параноидален?То же самое с массивом изображений.Также не стесняйтесь указывать на другие недостатки в моем коде, поскольку я знаю, что я не лучший программист.

Ответы [ 2 ]

3 голосов
/ 10 октября 2011

Конечно, вы должны отражать malloc s, когда вы свободны.

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] в каскаде.

2 голосов
/ 10 октября 2011

Глядя на код быстро, я бы сказал, что вы действительно упускаете бесплатное на плитках. Я бы предложил использовать анализатор памяти, чтобы выяснить это для себя. Например. http://www.cprogramming.com/debugging/valgrind.html Это даст вам хороший обзор выделенной памяти и возможных утечек памяти при выходе из программы.

...