IMCAT.DEV
로그인 가입
C++ 입문 자료구조

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

    코드 한 줄씩 동작 설명:

    1. int* ptr = new int; - 정수형 변수를 위한 동적 메모리를 할당하고, 해당 메모리의 주소를 ptr 포인터에 저장합니다.
    2. *ptr = 42; - ptr이 가리키는 메모리에 42라는 값을 저장합니다.
    3. std::cout << "Value: " << *ptr << std::endl; - ptr이 가리키는 메모리의 값을 출력합니다.
    4. delete ptr; - 할당받은 메모리를 해제하여, 메모리 누수를 방지합니다.
    5. 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로 설정하여 접근 방지

      6. 정리

    6. C++에서의 메모리 관리는 프로그래머의 책임이 큽니다.
    7. 동적 메모리 할당과 해제는 메모리 누수를 방지하기 위해 필수적입니다.
    8. 포인터를 사용하여 메모리 주소를 관리하는 것은 효율적인 메모리 사용을 돕습니다.
    9. 실무에서는 동적 배열, 객체 동적 생성 등의 패턴을 자주 사용합니다.
    10. 다음에 학습하면 좋은 주제: 스마트 포인터, RAII(자원 획득은 초기화) 패턴, 메모리 풀 관리.