학습
C++ 기본적인 메모리 관리
C++ 기본적인 메모리 관리 — 초급
기본적인 메모리 관리
1. 도입 (왜 배워야 하는가)
C++는 메모리 관리에 있어 많은 자유도를 제공하지만, 그만큼 책임도 요구합니다. 메모리 관리를 제대로 이해하지 못하면, 프로그램의 성능 저하, 메모리 누수, 예기치 않은 충돌 등의 문제가 발생할 수 있습니다. 특히 실무에서는 대규모 애플리케이션을 개발할 때, 효율적인 메모리 관리가 필수적입니다. 만약 메모리를 제대로 해제하지 않거나, 잘못된 메모리 접근을 시도하게 되면, 프로그램이 비정상적으로 종료되거나, 보안 취약점이 발생할 수 있습니다. 따라서, 기본적인 메모리 관리를 이해하는 것은 프로그래머로서 필수적인 역량입니다.
2. 핵심 개념 설명
동적 메모리 할당
- 정의: 프로그램 실행 중에 필요할 때 메모리를 할당하는 방법입니다.
- 비유: 마치 필요한 만큼의 공간을 임시로 빌려주는 것과 같습니다. 예를 들어, 친구의 방에서 필요한 물건을 잠시 빌려 사용하는 것처럼, 프로그램이 필요할 때만 메모리를 요청합니다.
- 정의: 다른 변수의 메모리 주소를 저장하는 변수입니다.
- 비유: 친구의 집 주소를 알고 있는 것과 같습니다. 주소를 알고 있어야 친구의 집에 가서 물건을 가져올 수 있습니다.
- 정의: 더 이상 필요하지 않은 메모리를 반환하는 과정입니다.
- 비유: 빌린 물건을 다시 돌려주는 것과 같습니다. 물건을 돌려주지 않으면 친구가 그 물건을 다른 사람에게 빌려줄 수 없듯이, 메모리를 반환하지 않으면 시스템 자원을 낭비하게 됩니다.
포인터
메모리 해제
| 용어 | 설명 |
|---|---|
| 동적 메모리 | 프로그램 실행 중에 필요에 따라 할당되는 메모리 |
| 포인터 | 메모리 주소를 저장하는 변수 |
| 메모리 해제 | 사용이 끝난 메모리를 반환하는 과정 |
3. 기본 코드 예제
다음은 동적 메모리 할당과 해제를 보여주는 간단한 코드입니다.
#include <iostream>
int main() {
int ptr = new int; // 동적 메모리 할당
ptr = 42; // 할당한 메모리에 값 저장
std::cout << "Value: " << *ptr << std::endl; // 값 출력
delete ptr; // 메모리 해제
return 0;
}
실행 결과:
Value: 42
코드 한 줄씩 동작 설명:
int* ptr = new int;- 정수형 변수를 위한 동적 메모리를 할당하고, 해당 메모리의 주소를ptr포인터에 저장합니다.*ptr = 42;-ptr이 가리키는 메모리에 42라는 값을 저장합니다.std::cout << "Value: " << *ptr << std::endl;-ptr이 가리키는 메모리의 값을 출력합니다.delete ptr;- 할당받은 메모리를 해제하여, 메모리 누수를 방지합니다.- C++에서의 메모리 관리는 프로그래머의 책임이 큽니다.
- 동적 메모리 할당과 해제는 메모리 누수를 방지하기 위해 필수적입니다.
- 포인터를 사용하여 메모리 주소를 관리하는 것은 효율적인 메모리 사용을 돕습니다.
- 실무에서는 동적 배열, 객체 동적 생성 등의 패턴을 자주 사용합니다.
- 다음에 학습하면 좋은 주제: 스마트 포인터, RAII(자원 획득은 초기화) 패턴, 메모리 풀 관리.
4. 실전 활용 예제
예제 1: 배열 동적 할당
쇼핑몰에서 장바구니에 담긴 상품의 개수를 동적으로 관리할 수 있습니다.
#include <iostream>
int main() {
int size;
std::cout << "장바구니에 담을 상품 개수를 입력하세요: ";
std::cin >> size;
int* cart = new int[size]; // 상품 개수만큼 동적 배열 할당
for (int i = 0; i < size; i++) {
cart[i] = i + 1; // 예시로 1부터 size까지의 상품 ID 저장
}
std::cout << "장바구니 상품 ID: ";
for (int i = 0; i < size; i++) {
std::cout << cart[i] << " ";
}
std::cout << std::endl;
delete[] cart; // 배열 메모리 해제
return 0;
}
예제 2: 객체 동적 생성
게임에서 캐릭터 객체를 동적으로 생성하여 관리할 수 있습니다.
#include <iostream>
class Character {
public:
Character(std::string name) : name(name) {}
void show() { std::cout << "캐릭터 이름: " << name << std::endl; }
private:
std::string name;
};
int main() {
Character* hero = new Character("전사"); // 캐릭터 객체 동적 생성
hero->show(); // 캐릭터 정보 출력
delete hero; // 객체 메모리 해제
return 0;
}
5. 흔한 실수와 주의사항
실수 1: 메모리 해제를 잊는 경우
int* ptr = new int(10); // 메모리 할당
// ... (사용 후)
delete ptr; // 메모리 해제를 잊으면 메모리 누수 발생
올바른 코드:
int* ptr = new int(10);
// 사용 후
delete ptr; // 반드시 메모리 해제
실수 2: 해제된 메모리 접근
int ptr = new int(10);
delete ptr;
// ptr = 20; // 이미 해제된 메모리에 접근, 정의되지 않은 동작
올바른 코드:
int* ptr = new int(10);
delete ptr;
// ptr = nullptr; // 포인터를 nullptr로 설정하여 접근 방지