C

[내배캠자습]C언어 챕터 8-2 : 동적할당과 메모리 소유권 문제

BreadMushroom 2026. 3. 29. 16:40

동적 할당의 세 가지 단계

1️⃣

메모리 할당(대여) 힙 메모리 관리자에게 필요한 바이트만큼의 메모리를 달라고 요청합니다. 힙 메모리 관리자는 해당 크기의 연속된 메모리를 찾아서 반환합니다. 반환된 값은 시작 메모리 주소입니다.

2️⃣

메모리 사용 할당된 힙 메모리 시작 주소를 가지고 원하는 작업 수행합니다. 이때 할당된 메모리 속 데이터는 쓰레기값입니다.

3️⃣

메모리 해제(반납) 힙 메모리 관리자에게 해당 메모리 주소를 돌려주면서 다 썼다고 알립니다. 힙 메모리 관리자는 해당 메모리를 점유되지 않은 메모리 상태로 바꿉니다. 메모리 주소를 돌려주지 않으면 메모리 누수(Memory leak) 발생합니다. 메모리 누수란, 해당 메모리가 점유 상태를 벗어나지 못해 사용가능한 메모리가 줄어드는 현상입니다.

동적 메모리 관련 함수

할당: malloc() 해제: free()

void* malloc(size_t size)

memory allocation의 약자. stdlib.h 헤더파일에 선언되어 있습니다. size 바이트 만큼의 메모리를 반환해줍니다. 할당 실패시 NULL을 반환합니다.

void free(void* ptr)

동적 할당 받은 메모리를 해제하는 함수. 다시말해, 메모리 할당 함수를 통해서 얻은 메모리 주소만 해제 가능합니다.

[좋은습관] malloc()을 작성했다면 곧바로 free()부터 작성하기.

동적 할당 받은 메모리 주소를 지역 변수에 저장해뒀다가 해제 안하고 함수가 종료되버리면, 해당 지역변수를 접근할 방법이 사라져 버립니다. 지울 방법이 없습니다. 이렇게 반납하지 않으면 메모리 누수가 발생하므로, 무슨 일이 있어도 free()부터 작성합시다.

Ex080201) malloc() 함수와 free() 함수 [중요 샘플 코드]

아래 소스코드를 따라서 작성해봅시다. 따라 작성한 소스코드의 출력 결과를 예측해보고, 예측 결과와 실행 결과를 비교해봅시다.

// Main.c

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

int main(void)
{
	size_t i;
	int* Nums = (int*)malloc(10 * sizeof(int));
	if (NULL == Nums)
	{
		return 0;
	}

	// Do something....

	free(Nums);
	Nums = NULL;

	if (NULL != Nums)
	{
		// TODO.
	}

	return 0;
}

 

[어려움]동적 할당 메모리 소유권

해당 메모리 공간의 주인이 누구냐는 아주 중요한 문제입니다. 왜냐면 반드시 책임 지고 해제해야 하기 때문입니다. 또 주인도 아닌데 마음대로 해제해버려도 문제입니다.

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

// Psudo code.

char* GetNewSpace()
{
	char* APStr;
	APStr = (char*)malloc(1024);
	if (NULL == APStr)
	{
		return NULL;
	}

	return APStr;
}