반응형
반응형

0. 요약

  1. new로 생성한 객체를 스마트포인터에 저장하는 코드를 별도의 한 문장으로 만들자
    • shared_ptr pw(new xxx);
  2. 이유
    • new 실행과 해당 자원을 스마트포인터 생성자로 전달하는 사이에 예외 발생시 자원 누수 발생!

1. 문제 사항

  1. 가정
    • 처리 우선 순위를 알려주는 함수 존재
    • 동적 할당한 Widget 객체에 대해 어떤 우선순위에 따라 처리를 적요하는 함수 존재
int priority();
void processWidget(std::shared_ptr<Widget> pw, int priority);

// processWidget을 사용
processWidget(new Widget, proiority());
  1. 위의 processWidget() 함수가 동작할까?
    • shared_ptr의 생성자는 explicit로 선언되어 있음
    • new Widget으로 만들어진 포인터가 shared_ptr 타입으로 암시적 변환이 되지 않음!
    • 아래와 같이 명시적으로 생성 후 호출하도록 변경
processWidget(std::shared_ptr<Widget>(new Widget), priority());
  1. 하지만 위의 문장은 자원이 누수될 가능성이 존재!
    • 위의 한 문장을 수행전 매개 변수 인자를 평가하는 순서 가짐
    • 본 예시에서는 3가지 단계를 거침
    • "new Widget" 을 실행 => shared_ptr 생성자를 호출 => priority() 함수 호출
    • 문제는 3개의 단계의 순서가 컴파일러 마다 다름!
  2. 만약 호출 순서가 아래와 같고, priority 에서 예외가 발생했다면?
    • "new Widget" 실행
    • priority() 실행
    • shared_ptr 생성자 호출
  3. new Widget으로 할당된 메모리가 해제되지 않아 누수 발생!

2. 해결 방법

  1. Widget를 생성해서 RAII에 저장하는 코드를 별도 한 문장으로 만들자!
  2. 그리고, 나머지 문장을 실행하자!
std::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());

참고

  1. Effective C++
반응형
반응형

0. 요약

  1. new와 delete 형태를 맞추자
    • new 에 []를 썼으면 delete에 []를 쓰자
    • new 에 []를 안썼으면 delete에 []를 쓰지 말자

1. new, delete의 동작 순서

  1. new

    • 메모리가 할당됨
    • 할당된 메모리에 한 개 이상의 생성자가 호출됨
  2. delete

    • 할당된 메모리에 한 개 이상의 소멸자가 호출됨
    • 메모리가 해제됨

2. 객체 1개 vs 배열로 할당/해제

  1. 한 개 객체 할당 시 메모리 구조
    • object
  2. 객체 배열 할당 시 메모리 구조
    • 객체 수(n) - object - obejct - ...
    • 위의 구조로 delete 연산자가 몇 번 호출 될지 쉽게 알 수 있음
  3. 주의 사항
    • delete 뒤에 [] 를 붙여줘야만 포인터가 배열을 가리키고 있다고 이해함
    • 만약 [] 가 없으면 단일 객체로 간주하고 1개의 객체만 delete 처리함

3. 결론

  1. new 와 delete 형태를 맞추자
    • new 에 []를 썼으면 delete에 []를 쓰자
    • new 에 []를 안썼으면 delete에 []를 쓰지 말자
  2. 배열 타입을 typedef으로 만들지 않도록 하자
    • string 또는 vector type을 활용하자!

참고

  1. Effective C++
반응형

+ Recent posts

반응형