0Pricing
C Academy · 강의

메모리 누수

누수를 찾아 방지합니다

메모리 누수은(는) CoddyKit의 무료 C Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

메모리 누수란 무엇인가

메모리 누수는 힙 메모리를 할당한 뒤 해제하지 않고, 해당 메모리를 가리키는 유일한 포인터까지 잃어버릴 때 발생합니다.

메모리는 프로그램이 종료될 때까지 예약된 상태로 남아 자원을 낭비합니다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 5;
    printf("%d\n", *p);
    free(p);
    return 0;
}

포인터 잃어버리기

전형적인 누수는 기존 할당을 해제하기 전에 포인터를 새 할당으로 덮어쓰는 경우입니다.

첫 번째 블록은 더 이상 접근할 수 없게 됩니다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    free(p);
    p = malloc(sizeof(int));
    *p = 10;
    printf("%d\n", *p);
    free(p);
    return 0;
}

반복문에서 발생하는 누수

반복문 안에서 반복할 때마다 해제하지 않고 할당하면 누수가 빠르게 누적됩니다.

다음 반복에서 포인터를 덮어쓰기 전에 해제하면 해결할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    for (int i = 0; i < 3; i++) {
        int *p = malloc(sizeof(int));
        *p = i;
        printf("%d ", *p);
        free(p);
    }
    printf("\n");
    return 0;
}

조기 반환으로 인한 누수

할당 후 조기에 return하면 정리 작업을 건너뛸 수 있습니다. 모든 종료 경로에서 항상 메모리를 해제하십시오.

#include <stdio.h>
#include <stdlib.h>

int process(int bad) {
    int *p = malloc(sizeof(int));
    if (bad) {
        free(p);
        return -1;
    }
    *p = 42;
    int r = *p;
    free(p);
    return r;
}

int main(void) {
    printf("%d\n", process(0));
    return 0;
}

goto 정리 패턴

goto로 이동하는 하나의 정리 레이블을 두면 한 곳에서 모든 메모리를 해제할 수 있어, 중복된 free 호출을 피할 수 있습니다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int rc = 1;
    int *p = malloc(sizeof(int));
    if (!p) goto done;
    *p = 7;
    printf("%d\n", *p);
    rc = 0;
done:
    free(p);
    return rc;
}

모든 할당에 대응시키기

가장 간단한 규칙은 다음과 같습니다. 각 malloc, calloc, realloc에는 정확히 하나의 대응하는 free가 있어야 합니다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *a = malloc(8);
    char *b = calloc(4, sizeof(char));
    a[0] = 'x';
    printf("%c %d\n", a[0], b[0]);
    free(a);
    free(b);
    return 0;
}

중첩된 할당 해제하기

구조체가 힙 메모리를 소유한다면 바깥 블록을 해제하기 전에 내부 포인터가 가리키는 메모리를 해제하십시오.

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int *data;
} Box;

int main(void) {
    Box *b = malloc(sizeof(Box));
    b->data = malloc(3 * sizeof(int));
    b->data[0] = 1;
    printf("%d\n", b->data[0]);
    free(b->data);
    free(b);
    return 0;
}

포인터 배열 해제하기

포인터 배열을 할당하고 각 항목이 별도의 할당인 경우, 먼저 모든 항목을 해제한 다음 배열을 해제하십시오.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n = 3;
    int **rows = malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        rows[i] = malloc(2 * sizeof(int));
        rows[i][0] = i;
    }
    for (int i = 0; i < n; i++) free(rows[i]);
    free(rows);
    printf("freed all rows\n");
    return 0;
}

소유권 관리

각 할당을 소유하고 해제할 책임이 누구에게 있는지 정하십시오. 반환된 포인터를 호출자가 해제해야 하는지 알 수 있도록 이를 문서화하십시오.

#include <stdio.h>
#include <stdlib.h>

char *make_greeting(void) {
    char *s = malloc(6);
    s[0]='h'; s[1]='i'; s[2]='\0';
    return s;
}

int main(void) {
    char *g = make_greeting();
    printf("%s\n", g);
    free(g);
    return 0;
}

누수를 찾는 도구

Valgrind와 AddressSanitizer 같은 도구는 모든 할당을 추적하고 해제되지 않은 할당을 보여 주어 누수를 보고합니다.

실제 프로그램을 검증하는 데 필수적인 도구입니다.

깔끔한 할당 수명 주기

전체 흐름은 다음과 같습니다. 할당하고, 확인하고, 사용하고, 모든 경로에서 해제한 다음 포인터를 NULL로 설정합니다. 이렇게 하면 프로그램에 메모리 누수가 발생하지 않습니다.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(4 * sizeof(int));
    if (!p) return 1;
    for (int i = 0; i < 4; i++) p[i] = i + 1;
    int sum = 0;
    for (int i = 0; i < 4; i++) sum += p[i];
    printf("sum = %d\n", sum);
    free(p);
    p = NULL;
    return 0;
}

빠른 확인

메모리 누수에 대한 이해를 확인해 보십시오.

복습

메모리 누수를 방지하는 방법을 배웠습니다.

  • 모든 할당에 정확히 하나의 free를 대응시키십시오.
  • 조기 반환과 오류를 포함해 모든 종료 경로에서 메모리를 해제하십시오.
  • 중첩된 할당과 포인터 배열의 할당은 안쪽부터 해제하십시오.
  • 명확한 소유권을 정의하고 Valgrind 같은 도구로 검증하십시오.

자주 묻는 질문

“메모리 누수” 강의는 무료인가요?

네 — “메모리 누수” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C Academy 강의 전체를 잠금 해제할 수 있습니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“메모리 누수”에서 뭘 배우나요?

누수를 찾아 방지합니다 브라우저에서 직접 실행하는 실습 코드로 C Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

C Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 C Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“메모리 누수” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 C Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 C Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. malloc과 free
  2. calloc과 realloc
  3. 메모리 누수
  4. 댕글링 포인터
← C Academy(으)로 돌아가기