Menu
Coddy logo textTech

동적 메모리 (new/delete)

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 14번째.

이제 포인터와 참조를 이해했으므로, 동적 메모리 할당을 통해 이를 실제로 활용해 보겠습니다. newdelete 연산자를 사용하면 런타임에 힙(heap) 영역에서 객체를 생성하고 소멸시킬 수 있습니다.

new를 사용하여 메모리를 할당하고 그에 대한 포인터를 반환받으세요:

int* num = new int;        // 단일 정수 할당
*num = 42;                 // 포인터를 통해 값 할당

Player* player = new Player("Hero");  // 객체 할당

모든 new는 메모리를 해제하기 위해 그에 대응하는 delete가 있어야 합니다:

delete num;      // 단일 객체 해제
delete player;   // 소멸자를 호출한 후, 메모리를 해제함

배열의 경우, new[]delete[]를 사용합니다:

int* scores = new int[5];    // 5개의 정수 배열 할당
scores[0] = 100;

delete[] scores;             // 배열 해제 - 대괄호에 주의하세요!

피해야 할 일반적인 실수:

// 메모리 누수 - delete를 잊음
int* ptr = new int(10);
ptr = new int(20);    // 첫 번째 할당에 대한 접근 권한을 잃음!

// 댕글링 포인터 - delete 후 사용
delete ptr;
*ptr = 5;             // 정의되지 않은 동작!

// 일치하지 않는 delete
int* arr = new int[10];
delete arr;           // 잘못됨! delete[]를 사용해야 함

삭제한 후에는 실수로 재사용하는 것을 방지하기 위해 포인터를 nullptr로 설정하세요. 수동 메모리 관리는 오류가 발생하기 쉬우므로 현대 C++에서는 스마트 포인터를 선호하며, 이에 대해서는 다음에 살펴보겠습니다.

challenge icon

챌린지

쉬움

newdelete를 사용한 동적 메모리 할당을 보여주는 간단한 메시지 저장 시스템을 만들어 보겠습니다.

코드를 구성하기 위해 두 개의 파일을 생성합니다:

  • MessageBox.h: 메시지 배열을 동적으로 관리하는 MessageBox 클래스를 정의합니다. 클래스는 다음을 포함해야 합니다:
    • 동적으로 할당된 문자열 배열을 가리키는 private 포인터
    • 현재 메시지 개수를 추적하는 private 정수
    • 최대 용량을 저장하는 private 정수
    • 용량을 인자로 받아 new[]를 사용하여 배열을 할당하는 생성자
    • delete[]를 사용하여 메모리를 적절히 해제하고 "MessageBox destroyed"를 출력하는 소멸자
    • 공간이 있으면 메시지를 추가하고 성공 시 true, 가득 찼을 시 false를 반환하는 addMessage(string msg) 메서드
    • 저장된 각 메시지를 개별 줄에 출력하는 printAll() 메서드
  • main.cpp: 입력으로부터 용량 값과 메시지 개수를 읽습니다. 그런 다음 그 개수만큼의 메시지 문자열을 읽습니다. new를 사용하여 힙에 MessageBox를 생성하고, 모든 메시지를 추가한 뒤, printAll()을 호출하고, 메모리 해제를 위해 MessageBox를 적절히 delete 합니다.

입력 형식은 다음과 같습니다:

  • 첫 번째 줄: 용량 (정수)
  • 두 번째 줄: 추가할 메시지의 개수 (정수)
  • 다음 줄들: 한 줄당 하나의 메시지

주의: 모든 new에는 그에 대응하는 delete가 필요하며, 모든 new[]에는 그에 대응하는 delete[]가 필요합니다. 삭제 후에는 포인터를 nullptr로 설정하는 것이 좋은 습관입니다.

main.cpp에서 #include "MessageBox.h"를 사용하여 헤더 파일을 포함하세요.

치트 시트

new를 사용하여 힙(heap)에 메모리를 동적으로 할당하고 해당 메모리에 대한 포인터를 얻습니다:

int* num = new int;        // 단일 정수 할당
*num = 42;                 // 포인터를 통해 값 할당

Player* player = new Player("Hero");  // 객체 할당

메모리를 해제하려면 모든 new에 대응하는 delete가 있어야 합니다:

delete num;      // 단일 객체 해제
delete player;   // 소멸자를 호출한 후 메모리 해제

배열의 경우, new[]delete[]를 사용합니다:

int* scores = new int[5];    // 5개의 정수 배열 할당
scores[0] = 100;

delete[] scores;             // 배열 해제 - 대괄호에 주의하세요!

피해야 할 일반적인 실수들:

// 메모리 누수(Memory leak) - delete를 잊음
int* ptr = new int(10);
ptr = new int(20);    // 첫 번째 할당된 메모리에 대한 접근 권한을 잃음!

// 댕글링 포인터(Dangling pointer) - delete 후 사용
delete ptr;
*ptr = 5;             // 정의되지 않은 동작(Undefined behavior)!

// 잘못된 delete 사용
int* arr = new int[10];
delete arr;           // 잘못됨! delete[]를 사용해야 함

삭제한 후에는 실수로 재사용하는 것을 방지하기 위해 포인터를 nullptr로 설정하십시오.

직접 해보기

#include <iostream>
#include <string>
#include "MessageBox.h"
using namespace std;

int main() {
    int capacity;
    int numMessages;
    
    // 용량과 메시지 수를 읽습니다
    cin >> capacity;
    cin >> numMessages;
    cin.ignore(); // 숫자 뒤의 개행 문자를 제거합니다
    
    // TODO: new를 사용하여 힙에 MessageBox를 생성합니다
    
    // TODO: 모든 메시지를 읽고 MessageBox에 추가합니다
    for (int i = 0; i < numMessages; i++) {
        string message;
        getline(cin, message);
        // MessageBox에 메시지를 추가합니다
    }
    
    // TODO: 모든 메시지를 표시하기 위해 printAll()을 호출합니다
    
    // TODO: 메모리 해제를 위해 MessageBox를 삭제합니다
    // 삭제 후 포인터를 nullptr로 설정하는 것을 잊지 마세요
    
    return 0;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨