最近写的一个程序,为了使接口简便,在返回字符串的时候不得已使用了stl::string,但是又担心如果此方法被频繁调用,可能会导致性能问题,于是尝试用一些底层机制去优化stl::string。
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(),用这个函数将内存中的信息打印出来,实现如下:
void PrintHex(char* Buffer, int Size, FILE* fp =stdout)
...{
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实现,不敢恭维啊!
分享到:
相关推荐
第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: ...
C#字符串删除指定字符串|C#字符串删除子字符串
java使用fastJson处理复杂Json字符串,直接获取key对应的value值
java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节; java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节; java 字符串转16进制 16进制转字符串 将两个ASCII字符合成一个字节; java ...
* 使用一个字符串分割另一个字符串 * * @param delimiter 边界上的分隔字符 * @param haystack 输入的字符串 * @param out 输出的字符串指针 * @return 分割成了多少个成员 */ int explode(char *delimiter, ...
Delphi 7.0 提取字符串中指定子字符串后的字符串,这个平时在字符处理时候使用几率也挺高的,获取指定字符串后面的字符串,比如获取扩展名等也可以用此方法,本例中要用到After函数,测试时,当单击按钮时,执行以下...
名称 :盛飞字符串截取函数 作用 :按指定首尾字符串截取内容(本函数为从左向右截取)
字符串相似度算法 字符串相似度算法 字符串相似度算法 字符串相似度算法 相似度 字符串
编写程序:从键盘上输入一个包含10个字符的字符串,把该字符串与程序中给定的字符串("bacdbcabca") //依次比较,统计两个字符串对应字符相等的数目。然后输出从键盘上输入的字符串, //并把两个字符串中对应字符不...
给写了2个方法,一个是直接截取单个需要的字符串,比如字符串string a="ab123456",我只需要提取3,那么就是单独截取就可以了,从2开始到4结束就行。 第二个是把所有的符合条件的字符串都截取出来,提取出来,比如...
1、菜单 内容包括:①输入字符串;②字符串动画显示;③退出. 2、输入字符串 选择该项后,可以输入一个字符串.该字符串即为动画显示时所显示的字符串. 3、字符串动画显示 显示字符串在一矩形框内从无到有,按指定方向...
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。 方法二:match() var str = "123" var reg = RegExp(/3/); if(str.match(reg)){ //包含; } ...
纯C语言实现字符串拆分操作,把字符串拆分成字符串数组,然后再输出。 使用sstream方法,作为底层驱动操作实现非常方便。
一个关于字符串匹配的算法,已经经过编译,希望对你有帮助
求两个字符串的最长公共字符串 输出全部位置信息,并输出字符串,相同字符串先输出所有位置信息在输出字符串 测试平台:XP/VS 2008 CN
本文实例讲述了javascript实现的字符串与十六进制表示字符串相互转换方法。分享给大家供大家参考。具体如下: 之所以写这个,是因为发现SQL注入和XSS中经常利用十六进制表示的字符串,比如 SELECT CONCAT(0x68656c6...
必须实现如下操作,字符串比较、求串的长度、判断串是否为空、将串置空、字符串赋值(包括两个字符串类复制,一个字符串赋值到CmyString对象)、求字符串中的一个字符或改变字符串中的一个字符(采用重载[]),...
这个代码可以添加一个新的字符串到已有的字符串数组中,并确保不会重复添加相同的字符串。具体来说,它首先创建了一个包含3个字符串的字符串数组`strArray`,然后定义了一个新的字符串`newStr`。接着,使用`ismember...
字符串 介绍 字符串 介绍 字符串 介绍 字符串 介绍
易语言字符串操作源码,字符串操作,字符串_取长度,字符串_取中间,字符串_取左边,字符串_取右边,字符串_替换,到宽字符,到多字节,取文本数据地址,取字节集数据地址,MultiByteToWideChar,WideCharToMultiByte