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가 보이지 않고.. 테스트 해봐도 마찬가지..