C언어메모리

검색

검색어를 입력해 개념, 문제, 필기를 찾습니다.

C언어 동적 메모리 할당 (malloc, free)

코딩C언어
읽는데 10분 소요
처음 쓰인 날: 2026-02-03
마지막 수정일: 2026-05-04
조회수:

요약

C언어 동적 메모리 할당의 기본 개념, malloc()과 free() 함수 사용법을 알아봅니다. 정보처리기사 실기에 자주 출제되는 동적 메모리 할당 문제를 풀기 위한 핵심 개념을 정리합니다.

동적 메모리 할당 핵심 정리

개념설명예시
malloc()힙 메모리에서 지정한 크기만큼 할당malloc(sizeof(int))
sizeof()자료형의 크기(바이트)를 반환sizeof(int) = 4
형변환malloc 반환값을 원하는 포인터 타입으로 변환 (생략 가능)(int*)malloc(...)
free()할당된 메모리를 해제free(p);

동적 메모리 할당이란? 기초

동적 메모리 할당은 프로그램 실행 중에 필요한 만큼 메모리를 할당받는 방법입니다.

일반 변수는 스택(Stack) 에 저장되고 크기가 컴파일 시점에 결정됩니다. 반면 동적 메모리는 힙(Heap) 에 저장되고 런타임에 크기를 결정할 수 있습니다. 자세한 내용은 메모리 구조를 참고하세요.

동적 메모리 할당 개념
스택은 크기가 고정되어 있지만, 힙은 malloc()으로 필요한 만큼 할당받을 수 있습니다.
구분스택 메모리힙 메모리
할당 시점컴파일 시실행 시
크기 결정고정가변
해제자동 (함수 종료 시)수동 (free 호출)
예시int arr[10];malloc(sizeof(int)*10)

malloc() 함수 기초

malloc() 은 Memory Allocation의 약자로, 힙 메모리에서 지정한 바이트만큼 공간을 할당합니다. 사용하려면 #include <stdlib.h>가 필요합니다.

c
코드 하이라이팅 중…
malloc 기본 사용법
malloc은 요청한 크기만큼 힙에서 메모리를 할당하고, 그 주소를 반환합니다.

malloc() 사용 패턴

c
코드 하이라이팅 중…

sizeof() 연산자

sizeof()는 자료형이나 변수의 크기를 바이트 단위로 반환합니다.

자료형sizeof() 결과
char1 바이트
int4 바이트
float4 바이트
double8 바이트
포인터4 또는 8 바이트 (시스템에 따라)
c
코드 하이라이팅 중…

포인터와 배열의 sizeof 차이, 구조체 padding이 크기에 어떻게 영향을 주는지는 sizeof 연산자 페이지에서 자세히 다룹니다.


형변환 (Casting) 기초

malloc()은 void* 타입을 반환합니다. void*는 "아직 타입이 정해지지 않은 범용 주소"로, 어떤 포인터 타입으로든 변환할 수 있습니다.

void*는 다른 포인터 타입으로 자동 변환되므로, 형변환을 생략해도 됩니다.

c
코드 하이라이팅 중…

2차원 배열 동적 할당 심화

2차원 배열을 동적으로 할당하려면 이중 포인터를 사용합니다.

c
코드 하이라이팅 중…
2차원 배열 동적 할당
이중 포인터 arr이 행 포인터 배열을 가리키고, 각 행 포인터가 실제 데이터를 가리킵니다.

2차원 배열 해제

할당의 역순으로 해제해야 합니다. 행 포인터 배열(arr)을 먼저 해제하면 각 행 데이터(arr[0], arr[1], ...)의 주소를 잃어버려서 해제할 수 없게 됩니다.

c
코드 하이라이팅 중…

정적 2차원 배열과의 차이

정적 2차원 배열 int a[3][3]은 메모리가 연속된 한 블록으로 잡히므로, aa[0]&a[0][0]이 모두 같은 주소를 가리킵니다 (타입만 다름).

정적 2차원 배열 메모리 구조
정적 배열은 연속된 한 블록으로 잡히므로, a, a[0], &a[0][0]이 모두 같은 주소입니다.

반면 동적 할당 int **arrmalloc여러 번 따로 호출하기 때문에 각각 독립적인 메모리 블록이 생깁니다.

c
코드 하이라이팅 중…
동적 할당 2차원 배열 메모리 구조 (빈 상태)
동적 할당은 malloc을 여러 번 호출해 별도 블록을 만들기 때문에 arr과 arr[0]이 다른 주소입니다. 다만 arr[0]과 &arr[0][0]은 둘 다 0행 데이터의 시작 주소로 같습니다.

동적 할당에서 arr[0]은 행 포인터 배열에 저장된 포인터 변수이고, arr[0][0]은 별도로 할당된 데이터 블록의 첫 번째 원소입니다. 그래서 arr(포인터 배열 주소)과 arr[0](데이터 블록 주소)은 서로 다른 블록에 있습니다. 단, arr[0]&arr[0][0]은 같은 주소를 가리킵니다(둘 다 0행 데이터의 시작점).

동적 할당 2차원 배열에 값이 채워진 상태
값이 채워진 후에도 구조는 동일합니다. 행 포인터(300번대)와 데이터(200번대)가 별도 메모리 블록에 있습니다.

free() 함수 기초

free() 는 malloc()으로 할당한 메모리를 해제합니다. 해제하지 않으면 메모리 누수(Memory Leak) 가 발생합니다. 메모리 누수란 프로그램이 더 이상 쓰지 않는 메모리를 반환하지 않아, 프로그램이 실행될수록 사용 가능한 메모리가 줄어드는 현상입니다.

c
코드 하이라이팅 중…
free 함수와 메모리 해제
free() 후에는 포인터를 NULL로 설정하는 것이 안전합니다.

구조체 포인터 동적 할당 패턴 기초

구조체 1개 분량을 malloc으로 할당하고, 화살표 연산자(->)로 멤버에 값을 넣은 뒤 free로 해제하는 흐름은 정처기 실기에서 가장 자주 등장하는 동적 메모리 결합 패턴입니다.

c
코드 하이라이팅 중…

세 단계는 항상 한 묶음으로 움직입니다. 구조체 종류가 바뀌어도 같은 형태가 그대로 적용됩니다.

단계코드의미
할당struct Person* p = (struct Person*)malloc(sizeof(struct Person));힙에 구조체 크기만큼 메모리 확보, 시작 주소를 p에 저장
접근p->age = 30;p가 가리키는 구조체의 age 멤버에 값 대입 ((*p).age와 동일)
해제free(p);할당받은 메모리를 시스템에 반환
구조체 포인터 동적 할당 3단계 메모리 변화
malloc 직후 → 멤버 대입 → free 직후의 메모리 상태 변화. p는 스택에, 구조체 본체는 힙에 자리잡습니다.

메모리 누수 주의

free를 호출하지 않으면 프로그램이 종료될 때까지 해당 힙 메모리는 시스템에 반환되지 않습니다. 함수가 끝날 때 스택의 포인터 변수 p는 사라지지만, 힙에 할당된 구조체 메모리는 그대로 남아 접근할 방법이 사라진 채 자리만 차지합니다. 이것이 메모리 누수(Memory Leak) 입니다.

c
코드 하이라이팅 중…

연결 리스트에서의 활용 심화

동적 메모리 할당은 연결 리스트에서 노드 1를 생성할 때 주로 사용됩니다.

c
코드 하이라이팅 중…

-> 는 포인터가 가리키는 구조체의 멤버에 접근하는 연산자입니다. n->c(*n).c와 같은 의미입니다.

연결 리스트 삽입 예시

c
코드 하이라이팅 중…

이 함수는 새 노드를 리스트의 맨 앞에 삽입합니다. 구조체 포인터와 함께 사용되는 패턴을 익혀두세요.


연습 문제


정보처리기사 실기 대비 문제


Footnotes

  1. 데이터와 다음 노드의 주소를 함께 담는 구조체 단위. 연결 리스트의 기본 구성 요소입니다.


관련 글

(41개)
제목태그시험
C언어 형변환 (Casting)
C언어
-
C언어 연결 리스트 뒤집기 (Reverse Linked List)
C언어
-
C언어 사용자 정의 함수 기초
C언어
-