C++ 초급 - 5. 포인터와 참조 (Pointers and References) (2 - 동적 메모리 할당 (new, delete))
2025. 2. 12. 18:42ㆍ프로그래밍 언어/C++
📌 5.2 동적 메모리 할당 (new, delete)
C++에서는 new와 delete 키워드를 사용하여 런타임(Run-time)에 동적으로 메모리를 할당 및 해제할 수 있다.
동적 메모리 할당을 활용하면 프로그램 실행 중 필요한 만큼 메모리를 할당할 수 있으며,
전역 변수나 지역 변수로 선언할 수 없는 대량의 데이터 처리나 가변적인 크기의 배열 관리가 가능하다.
그러나, 할당한 메모리를 해제하지 않으면 메모리 누수(Memory Leak)가 발생할 수 있으므로 delete를 사용하여 반드시 해제해야 한다.
📌 1. new와 delete를 사용한 동적 메모리 할당 및 해제
🔹 (1) new 키워드: 동적 메모리 할당
- new 키워드는 힙(Heap) 영역에 메모리를 동적으로 할당한다.
- 사용이 끝나면 반드시 delete로 해제해야 한다.
💡 기본 문법
데이터타입* 포인터변수 = new 데이터타입;
💡 예제: 동적 메모리 할당
#include <iostream>
int main() {
int* ptr = new int; // 정수형 데이터를 위한 메모리 할당
*ptr = 42; // 값 할당
std::cout << "할당된 메모리의 값: " << *ptr << std::endl;
delete ptr; // 메모리 해제
return 0;
}
🔹 출력 결과
할당된 메모리의 값: 42
💡 설명
- new int → 정수형 크기만큼 힙 영역에 메모리 할당.
- *ptr = 42; → 할당된 메모리에 값 저장.
- delete ptr; → 메모리 해제.
🔹 (2) delete 키워드: 동적 메모리 해제
- delete 키워드는 동적 메모리 할당된 데이터를 해제한다.
- delete를 사용하지 않으면 메모리 누수(Memory Leak)가 발생할 수 있다.
💡 기본 문법
delete 포인터변수;
💡 예제: 메모리 누수 방지
#include <iostream>
int main() {
int* num = new int(100); // 동적 메모리 할당 및 초기화
std::cout << "num의 값: " << *num << std::endl;
delete num; // 메모리 해제
num = nullptr; // 안전한 포인터 초기화
return 0;
}
🔹 출력 결과
num의 값: 100
💡 설명
- new int(100); → 정수형 메모리를 동적으로 할당하고 100으로 초기화.
- delete num; → 할당된 메모리를 해제.
- num = nullptr; → 해제된 포인터를 nullptr로 설정하여 잘못된 접근 방지.
📌 2. 배열의 동적 할당 (new[], delete[])
- 단일 변수뿐만 아니라 배열도 동적으로 할당 가능하다.
- new[]을 사용하여 배열을 할당하고, delete[]를 사용하여 해제해야 한다.
💡 기본 문법
데이터타입* 포인터변수 = new 데이터타입[배열크기]; // 배열 동적 할당
delete[] 포인터변수; // 배열 메모리 해제
💡 예제: 배열 동적 할당 및 해제
#include <iostream>
int main() {
int size = 5;
int* arr = new int[size]; // 정수형 배열 동적 할당
// 배열 초기화
for (int i = 0; i < size; i++) {
arr[i] = i * 10;
}
// 배열 출력
std::cout << "배열 요소: ";
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
delete[] arr; // 배열 메모리 해제
return 0;
}
🔹 출력 결과
배열 요소: 0 10 20 30 40
💡 설명
- new int[size] → size 크기의 정수 배열을 동적으로 할당.
- delete[] arr; → 배열 전체를 해제.
⚠ 주의: 단일 변수는 delete, 배열은 delete[]를 사용해야 함!
❌ 잘못된 코드 예시 (delete[] 없이 배열 삭제)
delete arr; // ❌ 배열 할당에 delete[]를 사용해야 함.
❌ 잘못된 코드 예시 (delete 없이 배열 사용)
int* arr = new int[5];
arr[0] = 10;
std::cout << arr[0] << std::endl;
// delete[] arr; // ❌ 메모리 해제를 하지 않으면 메모리 누수 발생!
📌 3. 메모리 누수 방지 및 올바른 해제 방법
동적 메모리 할당 시 올바르게 해제하지 않으면 프로그램이 종료될 때까지 메모리를 차지하게 되어
**메모리 누수(Memory Leak)**가 발생할 수 있다.
(1) 메모리 누수가 발생하는 코드
#include <iostream>
void memoryLeak() {
int* ptr = new int(50); // 메모리 할당
std::cout << "값: " << *ptr << std::endl;
// delete ptr; // ❌ 메모리 해제하지 않음 → 누수 발생!
}
int main() {
memoryLeak(); // 여러 번 호출하면 메모리 누적됨
return 0;
}
🔹 문제점
- delete ptr;을 호출하지 않으면, 프로그램이 종료될 때까지 할당된 메모리가 반환되지 않음.
- 메모리 누수 확인 방법:
- 프로그램 실행 후 메모리 사용량을 확인하면 지속적으로 증가하는 현상이 발생.
(2) 안전한 메모리 해제 방법
void safeMemory() {
int* ptr = new int(50);
std::cout << "값: " << *ptr << std::endl;
delete ptr; // ✅ 메모리 해제
ptr = nullptr; // ✅ 포인터 초기화 (잘못된 접근 방지)
}
🔹 올바른 메모리 해제 방식
- delete를 사용하여 할당된 메모리를 해제.
- ptr = nullptr;을 사용하여 해제된 포인터를 nullptr로 설정하여 잘못된 접근 방지.
📌 4. 정리
개념 | 설명 |
new 키워드 | 동적 메모리 할당 (new int;, new int[5];) |
delete 키워드 | 단일 메모리 해제 (delete ptr;) |
delete[] 키워드 | 배열 메모리 해제 (delete[] ptr;) |
nullptr 사용 | 안전한 포인터 초기화 (int* ptr = nullptr;) |
메모리 누수 방지 | 사용 후 반드시 delete 호출 및 nullptr 초기화 |