C++/게임 개발자를 위한 C++ 문법

배열 자체의 정적 선언과 요소의 개별적 동적 할당

iiblueblue 2024. 12. 26. 20:36
⊙ delete[]과 delete+반복문 사용처의 차이를 이해한다.
⊙ 배열 자체의 선언과 요소의 선언의 성질이 다른 상황을 이해한다.

 

배열 자체의 선언 ≠ 요소의 선언

코드 하나만 먼저 보도록 하자.

// Animal 타입의 포인터 배열 선언
Animal* animals[3];
animals[0] = new Dog();
animals[1] = new Cat();
animals[2] = new Cow();

과연 animals는 정적 배열로 선언 되었을까? 아니면 동적 배열로 선언 되었을까? 배열을 선언하는 문장 자체는 포인터 변수 배열을 선언한 것 처럼 보일 뿐 new를 사용하지 않았으니 동적 배열 같아보이지 않는다. 하지만 배열의 요소 하나하나는 new를 이용해서 동적 객체를 선언한 것을 볼 수 있다.

 

이 경우는 배열 자체는 정적으로 선언되었고 그 요소들은 동적으로 선언된 것이다. animals 자체는 정적 선언, animals[i]는 동적 선언된 상황에서 그렇다면 delete는 어떻게 해야하는 걸까?

 

정답은 반복문을 이용하여 delete를 각 요소마다 해주어야 한다는 것이다. 배열 자체도 동적으로 선언되었다면 delete[]를 사용했겠지만 배열 자체는 정적으로 선언되었기 때문에 delete[]는 사용할 수 없다. 대신 각 요소가 동적으로 선언되었으므로 메모리를 해제하기 위해서는 아래와 같은 코드가 올바르다.

// Animal 타입의 포인터 배열 선언
Animal* my_animals[3];
my_animals[0] = new Dog();
my_animals[1] = new Cat();
my_animals[2] = new Cow();

// 메모리 해제
for (int i = 0; i < 3; i++)
{
    delete my_animals[i];
    my_animals[i] = nullptr;
}

 

delete[]를 사용하면 프로그램이 중간에 중단되는 오류가 발생하게 된다.

결론적으로 delete와 delete[]를 사용하기 전에 해제하려는 변수나 객체가 동적으로 선언된 것이 맞는지 확인해야 한다. 그리고 new를 사용하지 않고 포인터만 사용해 선언한 변수나 객체는 동적으로 선언된 것이 아닌 포인터 변수, 포인터 객체가 선언된 것일 뿐이니 유의한다. 요소가 동적으로 들어간다고 해서 배열 자체가 동적 배열이 되는 것도 아니니 이점도 확인해야 한다.

 


 

배운 내용 정리

  • 배열 자체와 배열의 요소가 선언 방식이 각각 다를 수 있으니 확인해야 한다.
  • 배열 자체의 선언 상태를 확인하고 동적 배열이 아닐 시 반복문과 delete를 사용하여 메모리를 해제해야 한다.
  • 배열 자체도 동적으로 선언된 상태라면 delete[] 사용이 가능하다.