우선 제가 운영하고 있는 VoIP 서비스에 미디어 쪽 엔진에서 재생 관련하여 구현하며 이중 포인터를 접했고,
메모리 누수가 발생하였으며(Linked List (연결 리스트) 메모리 누수),
메모리 누수 해결을 위한 포스팅까지(_CrtDumpMemoryLeaks 을 이용한 메모리 누수 확인)...
포스팅이 계속 이어지는 것 같습니다.
그럼 앞서 포스팅했던 내용들을 토대로 버그 재발을 막기 위해 C언어 이중 포인터에 대한 malloc/free를 자세히 살펴보도록 하겠습니다.
우선 포인터는 배열과는 다르게 동적으로 메모리를 할당하는 녀석입니다.
기본적인 변수 타입의 사이즈 말고는 따로 malloc으로 메모리를 할당해주지 않으면 안 된다는 말입니다.
1. 우선 다음 기본 함수를 사용하기 위한 헤더가 필요합니다.
#include <stdlib.h>
void* malloc(size_t size);

2. 변수 선언
- 이중 포인터 변수를 선언합니다
- char **p_playlist;

3. 이중 포인터에 대한 메모리 할당
- 이차원 배열을 생각하면 쉬울 것 같습니다.
- p_playlist = (char**) malloc(sizeof(char*) * play_cnt);
-> 이차원 배열중에 첫 번째 배열에 대한 메모리를 할당 - for(i=0; i <play_cnt; i++) p_playlist [i] = (char*) malloc (sizeof (char) * 256);
-> 이차원 배열중에 두 번째 배열에 대한 메모리를 할당
- p_playlist = (char**) malloc(sizeof(char*) * play_cnt);

4. 버퍼에 스트링 어싸인
- p_playlist에 임시로 스트링을 삽입하여 줍니다.(서비스에선 이렇게 하면 안 되겠지요?)
- strcpy를 사용하기 위해선 다음 헤더도 선언해줘야 합니다
- #include <string.h>

5. 메모리 해제
- 서비스 운영 중 실수하여 며칠을 고생했던 부분이네요.
- for(i=0; i <play_cnt; i++) free(p_playlist [i]);
-> 이차원 배열중 두 번째 배열에 대한 메모리를 해제하는 부분 - free(p_playlist);
-> 이차원 배열중 첫 번째 배열에 대한 메모리를 해제하는 부분
-> playlist의 껍데기 메모리를 해제하는 부분이라고 생각하면 됨

전체 소스코드
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char **p_playlist;
int i;
int play_cnt = 5;
p_playlist = (char**) malloc(sizeof(char*) * play_cnt);
for(i=0; i<play_cnt; i++) {
p_playlist[i] = (char*)malloc(sizeof(char)*256);
}
strcpy(p_playlist[0], "TEST playlist 0");
strcpy(p_playlist[1], "TEST playlist 1");
strcpy(p_playlist[2], "TEST playlist 2");
strcpy(p_playlist[3], "TEST playlist 3");
strcpy(p_playlist[4], "TEST playlist 4");
for(i=0; i<play_cnt; i++) {
printf("playlist [ %d ] : %s\n", i, p_playlist[i]);
free(p_playlist[i]);
}
free(p_playlist);
return 0;
}
정리
포인터는 배열과 메모리 할당 방식이 다를 뿐 배열의 연장선이라고 봅니다.
원하는 크기만큼 버퍼의 사이즈를 잡고, 그 사이즈 안에서 버퍼를 사용하고, 최종적으로 버퍼를 비워줍니다.
예제를 할때는 느끼지 못하겠지만, 대규모 서비스에서 malloc/free를 경험해본다면 정말 작은 것부터 해나가야 한다는 것을 느꼈습니다.
누군가에겐 도움이 되었기를.........
'C언어' 카테고리의 다른 글
| Linked List (연결리스트) 메모리 누수 (0) | 2025.01.04 |
|---|---|
| _CrtDumpMemoryLeaks 을 이용한 메모리 누수 확인 (0) | 2025.01.04 |
| Linked List(연결리스트) 구현 (소스코드 포함) (0) | 2025.01.04 |