-
[Effective C++] 3장(2) - 자원 관리쾌락없는 책임 (공부)/Effetive C++ 요약본 2022. 3. 13. 17:11반응형
본 카테고리는 프로텍 미디어의 '이펙티브 C++'을 보고 요약하는 카테고리입니다.
3판을 기준으로 하며 전체 내용이 아닌 간략한 내용만을 요약하고 있습니다.항목 16 : new 및 delete를 사용할 때는 형태를 반드시 맞추자!
std::string *stringArray = new strd::string[100]; ... delete stringArray;
딱 보면 이상한 코드입니다. 이러면 이후 99개의 string들이 delete될 수 없습니다.
new 키워드로 동적 할당을 하면 아래 메모리 할당, 할당된 메모리에 대해 한개 이상의 생성자가 호출 됩니다. delete 표현식에서는 다른 2가지 내부 동작을 하게 됩니다. 할당된 메모리에 대해 한 개 이상의 소멸자 호출, 메모리 해제.
여기서 삭제되는 포인터는 객체 한개를 가리킬까요 아님 연결된 배열을 가리킬까요? 일단 new 로 힙에 만들어진 단일 객체 메모리 구조는 스택의 구조와 다릅니다!
그래서 배열을 삭제할 때는 꼭 []을 붙여야 합니다.
또한 typedef로 지정된 타입들에도 같은 일을 해줘야 합니다.
typedef std::string Address[4]; std::string *pal = new Address[4]; ... delete pal; // 무슨 일이 생길지 모른다! delete [] pal; // 음 좋고
그리고 가급적 typedef로 배열을 가리지 않는게 좋습니다! 또한 STL에 좋은 컨테이너들이 많이 있으므로 이걸 사용해보도록 합시다.
항목 17 : new 로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 하자
Widget 객체에 우선순위를 조정해주는 함수가 있다고 합시다.
int priority(); void processingWidget(std::tr1::shared_ptr<Widget> pw, int priority); ... processWidget(new Widget, priority());
그런데 위 processWidget(new Widget, priority());는 컴파일이 되지 않습니다. 왜냐면 함수는 shared_ptr이 필요한데 넣은건 원시 포인터니깐요.
processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());
일단 위 코드는 컴파일이 되는데 문제가 하나 있습니다! 여기서 자원을 흘릴 가능성이 있기 때문이죠. 왜 자원을 흘린다는건지 아래에서 알아보겠습니다.
일단 함수 processWidget에서는 인자들을 평가하는데 여기서 첫번째 인자는 2부분으로 나뉘게 됩니다.
- new Widget 실행
- tr1::shared_ptr의 생성자 호출
그래서 컴파일러는 함수 호출 전 위 2개 + priority 함수를 호출해야 하는데 여기서 문제가 3가지의 실행 순서가 컴파일러마다 다르다는 것입니다. (C#에서는 고정이라고 합니다) 그래서 만약 priority 함수 호출이 2번째가 된다면 new Widget은 포인터 소실이 될 가능성이 있습니다. 그래서 tr1::shared_ptr에 저장하기도 전 예외가 발생하는 것이죠.
( 자원 생성 시점과 자원이 자원관리 객체로 넘어가는 시점에 예외가 끼어들 수 있어서)
// new 로 생성한 객체를 스마트 포인터에 담는 문장을 하나로 저장 std::tr1::shared_ptr<Widget> pw(new Widget); processWidget(pw, priority()); // 해결 완료
그래서 이런 식으로 저장을 먼저 한 뒤 함수 호출을 해주면 문제가 해결됩니다.
반응형'쾌락없는 책임 (공부) > Effetive C++ 요약본' 카테고리의 다른 글
[Effective C++] 4장(2) - 설계 및 선언 (0) 2022.03.29 [Effective C++] 4장(1) - 설계 및 선언 (0) 2022.03.17 [Effective C++] 3장(1) - 자원 관리 (0) 2022.03.11 [Effective C++] 2장(2) - 생성자, 소멸자 및 대입 연산자 (0) 2022.03.10 [Effective C++] 2장(1) - 생성자, 소멸자 및 대입 연산자 (0) 2022.03.06