stl::string是怎麼實現的呢?腦海中有一個猜想,首先就是這樣:
class string
{
private:
char* m_str;
int m_len;
};
爲了驗證這個想法,於是用sizeof(string)將類型的長度打出來看看…………結果讓人大跌眼鏡,還要我不戴眼睛!在GCC中,sizeof(string)=4。怎麼可能嘛?如果就四個字節,哪裏放長度信息呢?
再次輸出更多信息來驗證:
string str = "abcde";
printf("addr=%08x, this=%08x, str=[%s]\n", (unsigned int)str.c_str(), *((unsigned int*)&str), str.c_str());
string自身的四個字節存儲的內容竟然就是所指向的字符串的指針!!!
難道?難道,string在GCC中的實現,就僅僅只是char*,如果調用str.length(),就是悄悄去調用strlen()?
再寫一個輸入內存的16進制字符串的函數PrintHex(),用這個函數將內存中的信息打印出來,實現如下:
...{
fprintf(fp, "===================================================== ");
char* p = NULL;
int i;
for (i=0, p = Buffer; i<Size; i++, p++)
...{
fprintf(fp, "%02x ", (unsigned char)*p);
if (i%16==15)
...{
fprintf(fp, " ");
}
}
fprintf(fp, " ===================================================== ");
}
打印一下內存的信息試試:
string str="abcde";
PrintHex(((char*)str.c_str())-20, 40);
分析16進制字符串,大概明白點string的內部了,看懂的部分大約是這樣的:
struct string_buffer
{
int Length;
int Capacity;
int unknown;
char Content[_Capacity]; // _Capacity = Capacity
};
而string只是指向這樣一個內存塊的content部分的指針。分配多個string,就會發現這些內存塊隔得很近。
以上分析說明:
1、string只是指向字符串池中內容部分的一個指針;(將string作爲參數或者返回值,性能都很高,等同於const string&這樣的參數)
2、字符串池的塊中緩存了長度和預留空間等信息,所以,不要使用C的字符串函數來操作string的任何內容,結果可能不一致。
最後,試試在VC中打印:sizeof(string),天哪!28個字節!微軟的STL實現,不敢恭維啊!