ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • vector의 clear 메소드에 대해
    IT/C++ 2019. 9. 29. 17:05

    clear라는 메소드 명을 보면 어떤 동작을 할 것 같은 메소드인지 감이오는가?

     

    http://www.cplusplus.com 을 보면 Removes all elements from the vector 라고 쓰여있다. 즉 vector의 모든 원소들을 Remove 해주는 메소드 라고 볼 수 있다.

     

    근데 Remove란 대체 어떤 동작일까? 좀 애매한 설명이지 않은가?

     

    다음과 같은 코드를보자

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <iostream>
    #include <vector>
     
    using namespace std;
     
    int main() {
        vector<int> a = { 1,2,3,4 };
     
        for (auto it : a) {
            cout << it << endl;
            a.clear();
        }
     
    }

    매 루프마다 clear를 호출해주는 메소드인데 직관적으로는 모든 원소들을 Remove 시켰으니 segfault error 가 날 것 같은 코드이다.

     

    근데 결과를 보면

     

    위와 같이 정상출력되는 것을 볼 수 있다.

     

    직관이랑 좀 위배되는거같으니 한번 대충이라도 내부 소스코드를 까보자.

     

    1
    2
    3
    4
    5
    6
    void clear() noexcept
    {    // erase all
        this->_Orphan_all();
        _Destroy(this->_Myfirst(), this->_Mylast());
        this->_Mylast() = this->_Myfirst();
    }

     

    위가 clear의 내부구현이고, _Destroy 메소드를 호출 한 후 first와 last iterator를 일치시키는 것을 알 수 있다.

     

    즉 모든 원소를 Destroy 시키니까 우리가 생각했던 clear 메소드의 동작과 제법 일치해 보인다. 그러면 저 _Destroy 메소드를 좀 더 파고내려가보자.

     

    1
    2
    3
    4
    5
    6
    7
    template<class _Alloc> inline void _Destroy_range1(
            typename allocator_traits<_Alloc>::pointer,
            typename allocator_traits<_Alloc>::pointer,
            _Alloc&, true_type)
    {    // destroy [_First, _Last), trivially destructible and default destroy
        // nothing to do
    }
     

    여러 메소드들을 거쳐 내려가보니 아무 동작도 안하는 _Destroy_range1 이라는 깡통 메소드 하나가 나온다.

     

    true_type이라는 파라미터 하나가 보이는데 소멸자가 있는타입인지 체크해주는 파라미터이다.

     

    즉 소멸자가 없는 int와 같은 타입에 대해서는 아무런 일도 수행하지 않는다. (대신 소멸자가 있는 타입들에 대해서는 delete를 호출해준다)

     

    때문에 실제 메모리상에서도 남아있고 메모리주소가 가리키는 값도 남아있기 때문에 Range Based for loop에서 값을 참조해서 출력할 수 있었던 것이다.

     

    capacity 메소드를 사용해 출력해보면 여전히 용량을 차지하고 있는 것을 알 수 있고 구글링 해보면 vector의 메모리릭 이슈는 swap 메소드를 사용해서 해결하라는 답변들을 볼 수 있다.

     

     

     

     

    결론

     

    clear라는 굉장히 직관적인 메소드도 이러한 생각지못한 부분들이 발생하게된다.

     

    엔지니어라면 이러한 추상화 Layer에 의한 블랙박스 부분들을 항상 챙기는 Detail함을 갖춰야 한다.

     

    또한 엔지니어라면 현재 참여하고 있는 프로젝트에서 사용되는 기술들에 대한 리스크까지 파악하고 있거나 최악의 경우라도 원인을 파악 할 수 있는 분석력을 갖추고 있어야 한다.

     

    'IT > C++' 카테고리의 다른 글

    C++ 신기한기능  (0) 2019.08.22
    pow 함수의 내부 구현에 대해...  (0) 2019.07.28
    C++에서 2차원 배열 인자로 받기  (0) 2019.06.29
    C++ 쓰는 회사에서 일해보고싶다  (0) 2019.06.29

    댓글

Designed by Tistory.