2011-10-10 5 views
3

내가 가지고있는 코드 조각이 메모리 누수를 일으킬 것이라고 생각합니다. 두 개의 2 차원 배열을 가진 데이터 구조가 있습니다. 하나는 int를 포함하고 다른 하나는 동적으로 할당 된 객체 (스프라이트)에 대한 포인터를 포함합니다. 데이터 구조는 타일 맵이며 int는 파일에서 읽은 각 위치의 숫자 인덱스입니다. 그 색인을 '타일'이라고 부릅니다. 이것은 행동을 위해 어떤 종류의 타일인지 알려줍니다 (즉, 플레이어는 흙이나 얼음보다 물에 대해 다르게 반응합니다). 객체는 각각의 위치에서 그리는 스프라이트입니다. 그 색인은 '이미지'라고합니다. 이 인덱스는 타일 맵에 그 위치에서 그릴 스프라이트를 알려줍니다.C- 메모리 누출 가능성?

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; 
} 

그런 다음 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하지만 한 번만 free'd. 나는 이것이 문제인지, int인지 보았지만, 타일 배열을 반복하고, 모든 행을 자유롭게하고, 루프를 통과하고 모든 열 (행을 포함)을 자유롭게해야한다고 생각합니다. 할당 된 것과 동일한 방식으로 사용됩니다. 저것은 할 필요가있는 무엇인가 또는 나는 단지 무지하고 그리고/또는 편집 성인가? 이미지 배열과 동일합니다. 또한, 내가 최고의 프로그래머가 아니라는 것을 알면서도, 코드 내 다른 결함을 지적 해주십시오.

+2

일부 malloc 유형이 잘못되었습니다. 'tiles'는 malloc (sizeof (int *) * N)'이어야하고'images'는'malloc (sizeof (sprite **) * M)'이어야합니다. –

+2

당신은 다음과 같은 메모리 프로파일 링 도구 리눅스에서 valgrind 또는 windows에서 정화? –

+0

@KerrekSB 무엇을 의미합니까? – Keelx

답변

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]이 계단식으로 해제되지 않습니다.

+0

감사합니다. 좋은 설명도. 그래도 이미지 배열은 어떨까요? – Keelx

+0

@Keelx'tm-> images [i] = malloc (sizeof (sprite *) * w)''자유로운 (tm-> images [i])'를 생각하게한다. – cnicutar

+0

그게 내가 생각한거야. 감사! – Keelx

2

코드를 빠르게 보면 타일에 무료가 누락되었다고 말할 수 있습니다. 나는 스스로를 알아 내기 위해 메모리 분석기를 사용할 것을 제안한다. 예 : http://www.cprogramming.com/debugging/valgrind.html 이렇게하면 할당 된 메모리에 대한 개요와 프로그램이 종료 될 때 메모리 누수가 발생할 수 있습니다.

+0

대단히 감사합니다.이 같은 것들을위한 매우 유용한 도구 인 것 같습니다. – Keelx