Visual Studio 2003으로 테스트 해본다..
VC6.0이나 다른 상위버전은 테스트 안해봐서 모르겠다..쩝 귀챠나서..
std:: string s1;
int nSize = sizeof(s1);
위와 같이 대충 끄적대고 나서.. 브레이크를 걸어보자..
nSize값은 28을 가지고 있다.
Watch창에서 s1을 살펴보면 다음과 같이 구성되어 있다.
s1
+--- std::_String_val<char,std::allocator<char>>
| (STL의 기본 Allocator)
+--- _Bx
| (문자열 데이터의 정보)
+--- _Mysize
| (문자열의 길이)
+--- _Myres
(컨테이너의 할당된 메모리 크기)
여기서 _Bx라는 넘을 살펴보면(xstring파일 참고) 아래과 같은 union으로 되어 있다.
union _Bxty
{ // storage for small buffer or pointer to larger one
_Elem _Buf[_BUF_SIZE];
_Elem *_Ptr;
} _Bx;
* _BUF_SIZE는 16으로 설정되어 있다.
대강 봐도 string의 데이터가 _BUF_SIZE보다 작으면 _Buf배열 안에..
크면 _Ptr의 포인터에 설정되게 구성되었으리라 판단된다..
테스트 해보니. 실제로 그렇다.. ^^;
string이 생성되면 문자열 데이터의 개수가 _BUF_SIZE 보다
작으므로(당연히) _Bxty._Buf[0]은 NULL값을 가지며 _Myres는 15라는 값을 가지게 된다.
그럼 15보다 큰 값을 넣어주면 어떻게 될까..
당연히 배열인 _Bxty._Buf는 무시되고 _Bxty._Ptr에 메모리가 할당되어 사용되어 진다.
그런데 _Myres값은 어떻게 변할까?.. 다시 말하면 할당되는 메모리의 최대 크기는
얼마씩 설정될까..?
20개의 문자열을 할당하고 테스트 해보면
_Myres의 값은 31의 값을 보여주게 된다. 즉 32byte가 할당되었다.
처음 16byte에서 단순이 2배로 설정한것일까?
이번엔 35개의 문자열을 할당하고 테스트 해보면
_Myres의 값이 47의 값을 보여주게 된다. @,@ 63이 아니다.. ㄷㄷㄷ
배수로 늘어나는 것이 아님을 보여준다...
stirng의 _Copy함수를 열어보면 그속에 답이 있다.
메모리를 재할당하는 과정에서 아래와 같은 size를 계산하는
단순하고도 오묘한? 수식을 볼 수 있다.
size_type _Newres = _Newsize | _ALLOC_MASK;
위에서 _Newsize는 새로 배정한 문자열의 길이이며..즉 35라는 값이 들어온다.
_ALLOC_MASK값은 15로 설정되어 있다.
이 수식에 의해 47이라는 값이 _Newres에 설정되고 이 크기만큼 할당되게 되는것이다.
뭐 나름대로 깊은 뜻이 있으리라.. 생각하자.~
* resize로 다른 값을 설정해서 같은 현상이 나타난다. 쩝.
참고로 다른 라이브러리는 reference count처리를 한다고 하지만 VC7에 포함된 STL string은
그러한 기능은 없는것 같다. ref count가 보이지 않고.. 테스트 해봐도 마찬가지..
댓글 없음:
댓글 쓰기