CString结构论

本文详细探讨了Microsoft MFC中的CString类的工作原理,包括其内部的写入复制技术(CopyBeforeWrite)。当一个CString对象初始化另一个对象时,它们共享内存,直到其中一个需要修改时才分配新内存。通过分析`GetBuffer`和`LPCTSTR`的使用,揭示了可能出现的错误,如忘记调用`ReleaseBuffer`导致的内存管理问题,以及类型转换带来的潜在风险。了解这些机制可以帮助程序员更安全、高效地使用CString。
摘要由CSDN通过智能技术生成

CString? 如果你接触过vc/mfc,呵呵,这个名字你一定见过。那么你就大胆的看下面的一个例子吧
----------------------------------
一段简单的代码如下:
----------------------------------

void C...Dlg::OnOK()
{
CString str;

strcpy((LPSTR)(LPCTSTR)str,"Hello!");
AfxMessageBox(str);

CString strL = "";
int n;
n = strL.GetLength();
AfxMessageBox(strL);

CDialog::OnOK();
}
说明:用(LPSTR)(LPCTSTR)这种怪怪的方法其实是故意的,目的是为了模仿现实问题。
现实是strcpy函数的调用在dll中做的,因为调用dll中函数没有参数类型检查,因此不用这种显式转换,而在这里没有办法,只是为了模仿strcpy的调用。
----------------------------------
大家可以跟踪看一看:

首先str得到Hello!没有问题
奇怪在下面,定义了第二个CString类型的对象,并赋初值为空字符,但跟踪观察发现,strL中同样也是Hello!指针地址是一样的,但是奇怪的是GetLength()却是0。既然长度为0,但却有值,而且还可以正常使用,比如用AfxMessageBox显示。但是如果我赋值不是空字符而是一个具体的,则没有问题。

上面的问题其实很简单,但我第一次遇到时却百思不得其解。所以现在回想着写下这段文字,目的是针对那些还没有注意CString结构的程序员们,至于高手们,呵呵,希望可以指点我一二,不甚感激!

解决上述问题前,先解释一个名词写入复制技术(CopyBeforeWrite):当使用一个CString对象a来初始化另一个CString对象b时,为了节省空间,新对象b并不分配空间,它所要做的只是将自己的指针指向对象a的那块内存空间,只有当需要修改对象a或者b中的字符串时,才会为新对象b申请内存空间。这种技术其实就是微软为了提高效率想出的一个怪招,既然有,我们就了解一下。
接下来,就分析一下CString的结构了:
CString大致可以理解成下面结构
|                  |                            |
|    Header   |           Data          |
|                  |                            |
也就是说CString其实包括一个header(数据头)和data(数据区)
CString是对于原来标准c中字符串类型的一种的包装。因为,通过很长时间的编程,我们发现,很多程序的bug多和字符串有关,典型的有:缓冲溢出、内存泄漏等。而且这些bug都是致命的,会造成系统的瘫痪。因此c++里就专门的做了一个类用来维护字符串指针。标准c++里的字符串类是string,在microsoft MFC类库中使用的是CString类。通过字符串类,可以大大的避免c中的关于字符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值