[완료] C++ 에서 delete에 대한 궁금점
글쓴이: 김일목 / 작성시간: 일, 2007/02/18 - 2:43오후
만약 이런식의 프로그램을 만든다면
class A {
int a[10];
}
class B : public A {
int b[10];
}
A* a = new B;
delete a;
요렇게 하면 subclass의 데이터가 delete 되는 거 맞나요?
그리고 또,
int* array = new int[10];
delete array; 요거랑
delete[] array; 요거랑
차이가 뭔가요?
new 명령어를 사용하면 메모리 상에 어떤 방식으로 할당량의 길이가 저장 되는 건가요?
Forums:
A * a = new B; delete
위 경우는 A, B 의 delete 가 모두 이루어집니다.
굳이 왜 배열에 대한 delete 연산을 구분 시켜 정의해 두었는지는 모르겠지만요.
명확하게 쓰라고 그렇게 정의한것 같기도 하고 (그냥 new int 와 new int[]) 가 다르니 delete 도 다르게 쓰라고 ㅋㅋ..
앞부터 하나씩 지우고 쓰기도 하리라 생각했는지..
만든 사람의 생각은 잘 모르겠지만, 암튼 그렇습니다.
아닙니다. 위의 경우
아닙니다.
위의 경우 A 클래스의 소멸자를 virtual 로 선언해야 제대로 삭제가 됩니다.
delete 에서 배열에 대해 [] 를 쓰는 것은 꼭 그래야 하기 때문입니다.
delete 는 대상 객체에 대해 소멸자를 한번만 호출하지만
delete[] 를 쓰는 경우 배열안의 각 원소에 대해 소멸자를 호출합니다.
따로 소멸자가
따로 소멸자가 정의되어 있지 않기 때문에 소멸자가 실행되냐 안되냐는 다른 문제 이구요.
" class B : public A " 를 통해 정의된 B 클래스의 인스턴스를 delete 하면 A를 상속받은 결과로 만들어진 A 내 데이터내용도 소멸됩니다.
delete[] 라면 뒤에 넘이 배열이라 배열을 삭제하는 것이고, 안 쓰면 그냥 int 포인터니까 int 공간만 삭제되는거겠죠.
각 원소에 대한 소멸자가 호출되는건 아닙니다. 뭐, 말의 의미는 같으시겠지만..
소멸자는 클래스에만 해당되고, C++은 모든 타입이 클래스인게 아니라 자바랑 C# 등의 객체만 다루는 언어랑은 다르지요.
음..
다른 문제가 아니지요. 확실히 소멸자를 정의해주지 않았기 때문에 컴파일러가 암시적으로 소멸자를 생성할 것이고 이 행동은 기본 소멸자를 지정해둔 것과 다르지 않습니다.
그렇게 되면 base 클래스에 자동적으로 virtual이 붙지 않기 때문에 위 같은 경우는 a의 인스턴스를 제거하는 것과 별반 다르지 않습니다. 만약 b에서 소멸자를 통해 해제해야 하는 자원 등이 남아있게 된다면 이는 리소스의 누수 문제를 야기시킬 수 있는 것이죠.
앞도 맞고 뒤도 맞고..
클래스 내에서 동적으로 생성된 메모리가 있으면 당연히 소멸자를 생성해주어야 하지요.. 그러나 위의 예에서는 동적 생성이 없습니다.
그러므로 위의 경우는 문제가 없습니다.
충격과 공포
정말로 문제가 없을까요?
실행 결과: https://ideone.com/R4ZtKY
클래스 B의 instance를 클래스 A에 대한 포인터로 받아서 delete를 시도한 영향은 소멸자에만 미치지 않습니다.
deallocation function에서도 그 차이가 보입니다. custom deallocation function에 전달되는 메모리 크기가 잘못되었죠. sizeof(B)가 아니라 sizeof(A)가 들어왔으니까요.
좀 오래된 질문 및 답변이라는 점을 감안하더라도, C++에서 polymorphism 기능을 사용할 기본 클래스는 가상 소멸자를 가져야 한다는 건 C++03 시절에도 중요한 원칙이었습니다.
설령 당장은 운이 좋아서 괜찮을 수 있다고 해도, 구태여 그런 위험을 무릅쓸 필요는 없습니다.
delete를 할당한 객체
delete를 할당한 객체 메모리를 반환하는것을 의미하는것이라면 B 데이타의 크기만큼 메모리를 반환하는게 맞습니다.(그러니까, 자식이 A와 B의 메모리 공간을 모두 차지하게 할당이 되고 또, 그만큼 delete시에 반환합니다.)
어떻게 그렇게 되는가? 는 new에 비밀이 있는데, 좋은글이 http://kldp.org/node/1073 에 있습니다.
delete 와 delete[]은 불려지는게 다른, 완전별개의 오퍼레이터입니다.
따라서 delete aaray는 잘못된 호출방법입니다. new[]로 할당을 했으면 delete[]를 호출해서 메모리를 반환 해주어야 합니다. 관련된 내용은 MEC++에 잘 나와있습니다.
poklog at http://poksion.cafe24.com/poklog/
poklog at http://poksion.cafe24.com/poklog/
좋은 답변 감사 합니다.
많은 도움이 되었습니다.
댓글 달기