grow buffer example

보물창고·2022년 12월 31일
0

사전 지식

  • placement new
  • 예외없는 move 처리

Ploblem

  • 기존에 만들어진 2개의 객체 있음.
    새롭게 할당된 4개의 객체에다가 2개를 move 하고 싶음

: 아래의 그림에서는 오른쪽 4개의 메모리를 할당하고, 생성자가 호출된 상태임.
-> 생성자에서 멤버에 대한 동적할당이 발생한다면, 메모리 소비하는 것임.

: 어차피 왼쪽의 2개를 오른쪽 2개에다가 이전하는 것이므로, 메모리만 할당하자는 것임.

  • 아래의 코드에서 p2의 멤버 자원을 동적할당하지 않고, p1으로 부터
    이동 받는 코드를 만들어라.

코드 작성해봄...

  • 1) operator new 와 placement new를 했으면, 반드시
    해제하는 코드도 명시적으로 작성하자.
    -> destructor 계속 호출됨...

  • 2) 동적할당 과 해제 짝을 맞춰야 함.
    : new 할당으로 한후, 해제를 분리시켜서 했떠니 오류 발생함.

  • 3) new ~ delete 짝을 맞추면 이상 없음.


오늘 시간 배운 거

  • 이전시간까지 큰 배열에 작은 배열 포인터를 이전하는 작업을 함.

  • but, 생각을 해보면, 큰 포인터의 2개 배열 원소를 굳이 할당할 필요가 없음.
    -> 어차피 작은 배열에 속한 2개를 이전할 것이기 때문임.

  • resource를 의미하는 것임.
    : 아래의 그림에서는 오른쪽 4개의 메모리를 할당하고, 생성자가 호출된 상태임.

: 어차피 왼쪽의 2개를 오른쪽 2개에다가 이전하는 것이므로, 메모리만 할당하자는 것임.


변경사항

: 이전 강의에서는 move 대입을 했지만, 이번에는 move 생성자를 호출하자.

  • 만드는 방법.
  1. 메모리가 큰 신규 버퍼는 메모리만 할당함.
  2. 위쪽에 위치한 2개의 버퍼는 placement new와 예외없는 이동생성자를 이용함.
    : 무조건 move 키워드를 사용하기 보다는 예외가 없는 이동을 부르는 것이 좋음.
  3. 2개의 버퍼는 placement new와 디폴트 생성자를 이용함.
  • 결과
    : 이렇게 만들면, 굳이 오른쪽에 있는 4개의 배열은 불필요한 생성자 2개를 호출할 필요가 없어짐.

  • 위의 예제의 경우는 디폴트 생성자가 있다는 가정하에 가능한 코드임.

  • 클래스에 디폴트 생성자가 없을 수 있기 때문에 , 최초 포인터도 메모리할당 + 생성자 호출을 따로 따로 하자.

  • 이어서 자원해제 코드를 작성하자.
    -1) 소멸자를 불러서 멤버들 해제
    -2) 객체 해제


vector에서는 어떻게 자원을 관리하는지 확인하자.

  • 아래 코드를 작성하고 출력하자.
vector<Test> v(2);
v.resize(4); 
cout << "--" << endl;

-> move가 이루어지는 것을 확인할 수 있음.
move 대입이 아닌 move 생성자를 사용하고 있는 것을 확인할 수 있음.

profile
🔥🔥🔥

0개의 댓글