Cstring之Getbuffer和ReleaseBuffer ios getcstring

做为VC程序员,无论是菜鸟或高手都曾用过CString.而且好像实际编程中很难离得开它(虽然它不是标准C++中的库).因为MFC中提供的这个类对我们操作字串实在太方便了,CString不仅提供各种丰富的操作函数、操作符重载,使我们使用起串起来更象basic中那样直观;而且它还提供了动态内存分配,使我们减少了多少字符串数组越界的隐患。但是,我们在使用过程中也体会到CString简直太容易出错了,而且有的不可捉摸。所以有许多高人站过来,建议抛弃它。
在此,我个人认为:CString封装得确实很完美,它有许多优点,如“容易使用 ,功能强,动态分配内存,大量进行拷贝时它很能节省内存资源并且执行效率高,与标准C完全兼容,同时支持多字节与宽字节,由于有异常机制所以使用它安全方便”其实,使用过程中之所以容易出错,那是因为我们对它了解得还不够,特别是它的实现机制。因为我们中的大多数人,在工作中并不爱那么深入地去看关于它的文档,何况它还是英文的。

1.CString实现的机制.

CString是通过“引用”来管理串的,“引用”这个词我相信大家并不陌生,象Window内核对象、COM对象等都是通过引用来实现的。而CString也是通过这样的机制来管理分配的内存块。实际上CString对象只有一个指针成员变量,所以任何CString实例的长度只有4字节.
即: int len = sizeof(CString);//len等于4
这个指针指向一个相关的引用内存块,如图: CString str("abcd");
___
____________| |
||| |
| 0x04040404|| | head部,为引用内存块相关信息
|____________|| |
str|___|
|'a'| 0x40404040
|'b'|
|'c'|
|'d'|
| 0 |

正因为如此,一个这样的内存块可被多个CString所引用,例如下列代码:
CString str("abcd");
CString a = str;
CString b(str);
CString c;
c = b;
上面代码的结果是:上面四个对象(str,a,b,c)中的成员变量指针有相同的值,都为0x40404040.而这块内存块怎么知道有多少个CString引用它呢?同样,它也会记录一些信息。如被引用数,串长度,分配内存长度。
这块引用内存块的结构定义如下:
struct CStringData
{
long nRefs; //表示有多少个CString 引用它. 4
int nDataLength; //串实际长度. 4
int nAllocLength; //总共分配的内存长度(不计这头部的12字节). 4
};
由于有了这些信息,CString就能正确地分配、管理、释放引用内存块。
如果你想在调试程序的时候获得这些信息。可以在Watch窗口键入下列表达式:
(CStringData*)((CStringData*)(this->m_pchData)-1)或
(CStringData*)((CStringData*)(str.m_pchData)-1)//str为指CString实例

正因为采用了这样的好机制,使得CString在大量拷贝时,不仅效率高,而且分配内存少。

2.GetBuffer

GetBuffer(int nMinBufLength)返回一个LPTSTR 类型指针。

getbuffer是为了让你使用CString类中,保存字符串缓冲区的那块指针.

GetBuffer传递的参数nMinBufLength大于原始字符串长度时,删除原来缓存,开辟更大的缓存。如果小于原始字符串长度时,则不开辟且原始数据长度保持不变。

如果你需要修改 CString中的内容,它有一个特殊的方法可以使用,那就是GetBuffer(bufLength),它的作用是返回一个可写的缓冲指针。

如果仅仅是读出CString中的内容,那么只需要用GetBuffer(0)即可。意思是:“给我这个字符串的指针,我保证不加长它”。
如果后面对CString还有其他操作,那么立刻ReleaseBuffer。

3.ReleaseBuffer

ReleaseBuffer可以理解为重新设置CString的字符串有效长度.
在MSDN中有这样一句话:
If you use the pointer returned by GetBuffer to change the string contents, you must call ReleaseBuffer before using any other CString member functions.
在对GetBuffer返回的指针使用之后需要调用ReleaseBuffer,这样才能使用其他Cstring的operations。否则会发生错误.

当你调用 ReleaseBuffer时,字符串的实际长度会被重新计算,然后存入 CString 对象中。

对于ReleaseBuffer的参数,缺省的是-1,但是不建议.因为-1表示使用当前的00结束符位置来确定新的长度.安全的做法,就是把这个CString的长度设为0,ReleaseBuffer(0)表示CString对象的分配的内存空间长度(nAllocLength)不变,只是其有效数据被置为空(nDataLength=0)。

VS2008 中,CString 的赋值操作 如:CStringteststring =_T(""),会释放掉其内存空间,建议用ReleaseBuffer(0)代替。


  

爱华网本文地址 » http://www.413yy.cn/a/25101017/330851.html

更多阅读

北广之星和中传有关系吗?手把手教你认清! 中传之星

临近艺考,同学们寻找培训班的需要紧迫,一些培训机构和个人为了某些利益和目的,在网络平台上散布关于北广之星的不实信息。北广之星和中传到底有没有关系,相信这是很多学生和家长所关心的,下面,小编就手把手教大家来认清北广之星。第一步:

妇人之仁 妇人之仁和善良的区别

周末无事,闲来说点时政。在对待难民的问题上德国总理默克尔一开始就犯了一个错误,典型的妇人之仁。首先,德国是率先公开表态愿意接受难民的国家,这种在他人处于为难之时肯伸出双手的做法无疑是值得赞许和肯定的,而无论这样做的目的是什么

张怀远:中国传统文化之弊和未来的出路

小序:中国传统文化与文化传统之辩和我们的态度什么是文化传统,什么是传统文化?两者的关系怎样?不少人对此好像一直若明若暗,常常将两者混用,甚至文化舆论界似乎也尚未彻底厘清。李慎之先生对此已经做过很好的梳理。他指出,“传统文化就是中

张仪与楚国之纠结和相关的屈原事迹 张仪许诺楚国

.《史记》记张仪的事迹、年代大多正确,但是“把苏秦的经历提早了约三十年”。《战国策》中,又把好多张仪的传说,混在史实之中,致使张仪事迹含混不清。现就张仪与楚国和屈原相关的问题,略加梳理,以求教于方家。一 张仪得势前的传说.(一) “

声明:《Cstring之Getbuffer和ReleaseBuffer ios getcstring》为网友画檀烟分享!如侵犯到您的合法权益请联系我们删除