当前位置:C++技术网 > 资讯 > string系列:4 string和string数组内部的实现原理深入剖析

string系列:4 string和string数组内部的实现原理深入剖析

更新时间:2015-06-26 21:14:21浏览次数:1+次

    前面介绍了CString数组的内部原理分析,作为C++自带的string,也是必须好好分析一把的。
    string与MFC中的CString是很不一样的。内部的机制也是不一样的。所以需要深入的详细说明一下。
    我们在定义一个string对象时,string分配的内存就只有32字节。直接用于存储字符串的缓冲区大小只有16字节。也就是说,如果赋值给string对象的字符串大小不超过16字节,包括空字符在内的16个字符,那么字符串就直接存入string对象内部的16字节的缓冲区中。但是,如果超出了16字节,那么此时这个小缓冲区就不是存储字符串的了,而是存储字符串缓冲的地址的了。
    那么你会问,这个小缓冲区位于string对象的哪里呢?这个小缓冲区是位于string对象32字节内存的第9个字节开始的16个字节大小的缓冲区。
    紧接着小缓冲区的四个字节,表示的是string对象存储的字符的个数,不包含结尾的空字符。而至于再后面的就不用细究了。
    比如,string str = "1234";,那么str的内存是下面这样的:
    00 00 00 00 cc cc cc cc 31 32 33 34 00 cc cc cc cc cc cc cc cc cc cc cc 04 00 00 00 0f 00 00 00
    而如果string str = "123456789012345";,那么str的内存是下面这样的:
    00 00 00 00 cc cc cc cc 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 00 0f 00 00 00 0f 00 00 00
    而超出16字节后,string str = "12345678901234567";,那么str的内存是下面这样的:
    00 00 00 00 cc cc cc cc c0 87 5c 00 cc cc cc cc cc cc cc cc cc cc cc cc 11 00 00 00 0f 00 00 00
    这样你就一目了然了。以上就是string 的内部原理分析。
    下面看看string 数组的分析,让你对string 数组也有一个较为深入的了解。可以对比CString数组来学习。
    CString数组的数组元素,每一个都是4字节的大小,实际上就是存储的CString对象的指针罢了。而string数组却直接存储的是string对象本身。因为string对象占32字节,那么,string数组中的元素都是32字节的大小。
    如此一来,CString数组和string数组的元素个数是固定的,数组的元素大小本身也是固定的。为什么说我们可以动态调整数组元素的大小呢?
    可能看了CString数组分析,说的不够透彻吧。只能说,这两个数组本身是固定的,但是使用CString和string数组后,因为CString和string本身的动态调整的特性,使CString数组和string数组具备了这种能力,是间接实现的能力。因为数组还是原来的数组,只是数组中的元素的特性使数组能力变强罢了。
    在使用这个数组时,我们只需要把CString数组里面的元素当做是一个CString对象即可,底层机制做了这样的处理。而string数组元素本身就是存储的string对象本身。string数组中的元素就是一个string对象,所以在存入的字符小于等于15个的时候,就直接存在string对象的小缓冲区中,如果超出15个,那么就在string对象存储一个缓冲区指针,计入字符个数。
        
string strArr[] = {"1string","2string","3string890123456"};

    以上语句执行后,strArr数组的内存是下图所示的:
string数组内部结构
    由图中可以看到,每一个string对象都占用了32字节,前面两个元素string对象因为存入的字符小于15个,因此是直接存入string对象的。而第三个string中的字符超出了16个,就只存入了0x00518760,即字符串的缓冲地址。通过查看0x00518760,我们看到了缓冲区的内容“3string890123456”,如下图所示:
第三个元素string的字符串缓冲的内容
    到此我们就分析完了string对象本身的内部结构,然后对比CString数组和string数组的差别,最后用图解方式清晰的看到了string数组的实现原理。相信通过这些分析,可以让你对string和string数组有一个非常深入的了解。如果有哪里说得不准确或者错误之处,请指出,虚心求教。