
동적이다 라는 것은 런타임(runtime)에서 메모리를 동적으로 할당하기 때문에 동적(dynamic) 이라는 특징을 가진다. 그렇기에, 정적 메모리와 동적 메모리는 사용하는 방식이나 로직에서 큰 차이는 없다.
핵심적인 차이는 메모리가 할당되는 시점과 관리 방식에 있다. 실행 시점만 다를 뿐, 기본적으로 데이터에 접근하고 사용하는 로직은 동일하다.
그렇다면 정적 언어인 C언어에서 동적 배열을 구현해보자.
구현과정에서 #include <stdlib.h>를 불러와, 동적 메모리 할당 함수 malloc,realloc,free 를 적극 사용할 것이다.
malloc Memory Allocation메모리를 동적으로 할당하는 함수이다. 지정한 크기 만큼의 연속적인 메모리 공간을 할당하고, 해당 메모리의 시작 주소를 반환한다. 할당된 메모리의 초기값은 정의되지 않으므로 초기화가 필요하다.
void *malloc(size_t size);
size : 할당할 바이트 크기 예( sizeof(int) * 10 ).
return : 성공 시 메모리의 시작 주소를 반환, 실패 시 NULL 반환.
realloc Reallocate Memory기존에 할당된 메모리 크기를 변경하는 함수이다. 기존 메모리 블록을 확장하거나 축소할 수 있다. 새로운 크기를 제공하면, 필요한 경우 메모리 블록을 이동시키고 데이터를 복사한다.
void *realloc(void *ptr, size_t size);
ptr : 기존에 할당된 메모리의 포인터
size: 새로운 메모리 크기 (바이트 단위)
return :성공 시 새 메모리 블록의 시작 주소, 실패시 NULL 반환.
free Free Memory동적으로 할당된 메모리를 해제하는 함수이다. 할당된 메모리를 더 이상 사용하지 않을 때 호출하여 메모리를 반환한다. 메모리를 반환하지 않으면 Memory Leak(메모리 누수)가 발생할 수 있다.
void free(void *ptr);
ptr : malloc or realloc 으로 할당된 메모리의 포인터
return : 없음
#include <stdio.h>
#include <stdlib.h>
int main(){
int initial_size = 5;
int *arr = (int *)malloc(initial_size * sizeof(int));
// 배열 초기화
for (int i = 0; i < initial_size; i++) {
arr[i] = i + 1;
printf("%d ", arr[i]);
}
}
malloc을 사용하여 동적 메모리를 할당한다. 그 다음에 배열의 초기 값을 설정하여 결과적으로 {1,2,3,4,5} 가 저장된다. int new_size = 10;
arr = (int *)realloc(arr, new_size * sizeof(int)); // 크기를 10으로 확장
// 새로운 값 추가
for (int i = initial_size; i < new_size; i++) {
arr[i] = i + 1;
}
배열의 크기를 변경하기 위해 새 크기를 설정한 뒤, realloc 을 사용하여 기존 배열의 크기를 new_size 만큼 확장한다. 기존 데이터는 새로운 메모리 블록으로 복사된다.
그 다음에 새로 추가된 배열에 요소를 추가하여 결과적으로 {1,2,3,4,5,6,7,8,9,10} 이 저장된다.
free(arr); // 메모리 해제
malloc , realloc으로 할당된 메모리를 해제한다. 메모리를 해제하지 않으면, 프로그램 종료 후에도 해당 메모리가 반환되지 않아 Memory Leak(메모리 누수)가 발생할 수 있다.
일반적으로, 프로그램이 종료 시, 운영체제는 해당 프로세스가 할당된 모든 메모리를 자동으로 해제합니다. 그러나, 이는 동적 메모리 할다에서 발생한 문제와는 다르다.
1. 프로그램 종료 시의 메모리 반환
프로세스 종료 시, 운영체제는 해당 프로세스가 할당한 모든 메모리를 자동으로 해제합니다. 즉, 프로세스가 종료되면 스택 메모리, 힙 메모리, 코드 영역 등 모든 메모리 공간이 운영 체제에 의해 회수됩니다.
따라서, 프로그램이 종료되면 malloc으로 할당한 메모리도 운영 체제가 회수하지만, 이 메모리 누수의 문제는 프로그램 실행 중에 발생합니다.
2. 메모리 누수와 프로그램 실행 중
1. 프로그램 실행 중:
2. 프로그램 종료 후:
free()를 호출하지 않아도 운영체제가 모든 메모리를 회수하여 시스템에서 다른 프로세스가 사용할 수 있게 됩니다.free()를 호출하지 않아도 프로그램이 종료되면 운영체제는 해당 프로세스의 메모리를 회수합니다.
그러나 프로그램이 실행 중일 때 메모리 누수가 발생하면, 시스템 자원이 낭비되고, 이는 프로그램 성능 저하나 시스템 자원 부족을 일으킬 수 있습니다.
그러므로 동적 메모리를 할당한 후에는 반드시 free()를 호출하여 메모리를 해제하는 것이 중요하며, 프로그램 실행 중에 메모리 자원을 낭비하지 않도록 해야 합니다.