- 힙 메모리
- 메모리 레이아웃(메모리 구조)
메모리 레이아웃은 크게 스택 메모리, 힙 메모리, 코드 섹션, 데이터 섹션으로 나뉩니다.
- 코드 섹션과 데이터 섹션
코드 섹션: 우리가 작성한 소스코드들이 빌드된 결과물들이 저장되는 곳입니다.
데이터 섹션: 전역 변수와 정적 변수등이 저장되는 곳입니다.
- 스택 메모리의 단점
1.스택 메모리에 저장되는 지역 변수(배열 등)의 크기는 컴파일 타임에 고정됩니다.
런타임에 더 필요해진다 해도 크기를 늘릴 수 없습니다.
2.함수가 종료되면 해당 스택 프레임에 더이상 접근 불가능합니다.
즉, 지역변수의 수명은 함수의 수명과 함께합니다.
더 오래 보존하려면 전역변수 혹은 정적변수로 선언해야 합니다.
근데 이 변수들은 너무 또 극단적입니다. 프로그램의 수명과 함께합니다.
런타임 시에 프로그래머가 원하는 만큼(1번 만족)
원하는 때에 생성 및 삭제(2번만족) 가능한 메모리가 필요합니다.
- 힙 메모리(Heap Memory)
프로그래머의 메모리 할당과 해제를 통해 관리되는 동적 할당 영역입니다.
스택 메모리는 함수의 호출 및 종료에 따라 자동으로 정리됩니다만, 힙메모리는 아닙니다.
프로그래머가 원하는 만큼, 원하는 때에 할당 및 반납이 가능합니다.
이것이 힙 메모리의 장점입니다.
- 힙 메모리의 단점
1.스택 메모리에 비교해 할당/해제 속도가 느립니다.
스택 메모리는 자료구조 스택의 특성상 할당 및 해제에 O(1) 시간이 걸립니다.
힙 메모리는 할당 받아오려면 사용중이지 않은 메모리이면서 크기가 맞는지 체크 후 제공됩니다.
또한 메모리 공간에 구멍(메모리 단편화)이 생길 수도 있어서 효율적인 메모리 관리가 어렵기도 합니다.
2. 프로그래머가 직접 메모리 할당 및 해제 해야합니다.
메모리 할당만 하고 해제는 안하는 실수를 할 여지가 있습니다.
- 동적할당과 메모리 소유권 문제
- 동적 할당의 세 가지 단계
1.메모리 할당(대여)
힙 메모리 관리자에게 필요한 바이트만큼의 메모리를 달라고 요청합니다.
힙 메모리 관리자는 해당 크기의 연속된 메모리를 찾아서 반환합니다.
반환된 값은 시작 메모리 주소입니다.
2. 메모리 사용
할당된 힙 메모리 시작 주소를 가지고 원하는 작업 수행합니다.
이때 할당된 메모리 속 데이터는 쓰레기값입니다.
3. 메모리 해제(반납)
힙 메모리 관리자에게 해당 메모리 주소를 돌려주면서 다 썼다고 알립니다.
힙 메모리 관리자는 해당 메모리를 점유되지 않은 메모리 상태로 바꿉니다.
메모리 주소를 돌려주지 않으면 메모리 누수(Memory leak) 발생합니다.
메모리 누수란, 해당 메모리가 점유 상태를 벗어나지 못해 사용가능한 메모리가 줄어드는 현상입니다
- 동적 메모리 관련 함수
할당: malloc() / calloc()
재할당: realloc()
해제: free()
기타: memset() / memcpy() / memcmp() / …
- void* malloc(size_t size)
memory allocation의 약자. stdlib.h 헤더파일에 선언되어 있습니다.
size 바이트 만큼의 메모리를 반환해줍니다.
할당 실패시 NULL을 반환합니다.
- void free(void* ptr)
동적 할당 받은 메모리를 해제하는 함수.
다시말해, 메모리 할당 함수를 통해서 얻은 메모리 주소만 해제 가능합니다.
- malloc()을 작성했다면 곧바로 free()부터 작성하기.
동적 할당 받은 메모리 주소를 지역 변수에 저장해뒀다가 해제 안하고 함수가 종료되버리면,
해당 지역변수를 접근할 방법이 사라져 버립니다. 지울 방법이 없습니다.
이렇게 반납하지 않으면 메모리 누수가 발생하므로, 무슨 일이 있어도 free()부터 작성합시다.
- malloc() 함수와 free() 함수

- 동적 할당과 포인터 연산 1

- 동적 할당과 포인터 연산 2

- void* realloc(void* ptr, size_t new_size)
이미 동적할당 받은 메모리 시작 주소 ptr을 new_size 바이트로 재할당 해주는 함수.
새로운 크기가 허용하는 한 기존 데이터를 그대로 유지해줍니다.
- malloc() 함수와 realloc() 함수

- 동적 할당 메모리 소유권
해당 메모리 공간의 주인이 누구냐는 아주 중요한 문제입니다.
왜냐면 반드시 책임 지고 해제해야 하기 때문입니다.
또 주인도 아닌데 마음대로 해제해버려도 문제입니다.
// Psudo code.
char* CombineString(const char* LHS, const char* RHS)
{
char* APStr;
size_t Size = strlen(LHS) + strlen(RHS);
APStr = (char*)malloc(Size + 1);
if (NULL == APStr)
{
return NULL;
}
/* 복사 생략 */
/*
호출자 입장에선 CombineString() 함수가 내부에서
동적 메모리를 할당해서 반환한다는 사실을 어떻게 알 수 있을까요?
이처럼 동적할당된 메모리의 해제 문제는 복잡합니다.
C++에서는 RAII라는 개념을 통해 메모리 해제 실수를 구조적으로 막을 수 있습니다.
*/
return APStr;
}
- 구조체
- 구조체(Structure)
필요한 여러 자료형의 변수들을 한데 묶어서 하나의 자료형처럼 만들 수 있습니다.
struct 구조체명
{
자료형 변수명;
...
};
- 구조체 정의

- 구조체 변수 선언

- 구조체 멤버 접근 연산자

- 함수의 인자로 구조체 변수 전달

- 문제의 코드

- 구조체와 객체지향 프로그래밍
나만의 자료형처럼 만든다는 것은 OOP에서 하나의 물체를 정의하는 것과 같습니다.
나만의 자료형으로 물체(객체)를 정의하고,
동적할당을 이용해서 물체를 생성 후 원하는 때에 해당 물체를 제거합니다.
이는 객체지향 프로그래밍과 유사합니다.
- typedef
- typedef
type definition의 약자. 이미 정의되어 있는 자료형에 새로운 별명을 지어줍니다.
- typedef 1

- size_t 자료형도 사실 typedef unsigned long long size_t
_t가 접미사로 붙으면 typedef 되었다고 보면 됩니다.
- typedef 2

- typedef 3

- 초기화 방법

- typedef와 함수 매개변수 자료형

- pointer to structure
구조체도 포인터 자료형이 가능합니다.

- 또다른 구조체 멤버 접근 연산자 ->
구조체 포인터에 역참조 연산자와 . 연산자를 합친 연산자가 -> 연산자.
우선순위도 1순위인 연산자라서 괄호 안쳐도 됩니다.
- -> 연산자

- 여러 개의 반환 값
구조체를 함수 반환 자료형으로 쓰면 실질적으론 여러개의 값 반환 가능합니다.

- 구조체 배열

- 구조체와 클래스
- Human 구조체

- 객체지향 프로그래밍의 시작
위 예제가 별거 아닌것처럼 보이지만, 객체지향 프로그래밍의 시작과도 같습니다.
Park이라는 Human_t 객체를 만들어 낸 예제입니다.
객체지향 프로그래밍 언어는 객체 간의 상호작용에 중점을 둔 언어입니다.
지금까지 배운 내용으로 객체지향 프로그래밍을 살짝 맛보도록 해봅시다.
- 구조체에 멤버 변수만 선언 할 수 있는건 아닙니다.
객체지향 프로그래밍으로 넘어가면서 구조체에는 멤버 함수도 선언 할 수 있습니다.
- 멤버 함수 1

- 멤버 함수 2

- 클래스 만들어보기

- 구조체와 클래스가 완전히 똑같은건 아닙니다.
클래스는 접근 제한 지정자와 상속 등 다양한 기능들이 추가적으로 지원됩니다.
- enum
- 열거형(Enummeration)
정수에 별명을 붙여서 소스코드를 이해하기 쉽게 해줍니다.
enum 열거형명
{
멤버01,
멤버02,
...
};
- enum 1

- enum 2

- 열거형도 typedef가 가능합니다.
되도록이면 typedef를 이용해서 가독성을 더 끌어올려봅시다.
- enum과 typedef

'C 언어' 카테고리의 다른 글
| [Unreal Engine 8기] C언어 포인터 심화 (1) | 2026.03.04 |
|---|---|
| [Unreal Engine 8기] C언어 5일차 (0) | 2026.02.27 |
| [Unreal Engine 8기] C언어 4일차 (0) | 2026.02.26 |
| [Unreal Engine 8기] C언어 3일차 (0) | 2026.02.25 |
| [Unreal Engine 8기] C언어 2일차 (0) | 2026.02.24 |