一个关于c++字符串处理和delete[]与delete差别的问题
---张吕全
先看下面一个字符串处理的小例子
CString str = "zhongguo";//在c++builder中CString 对应的类型AnsiString 其余一样
CString strtwo = str;//值拷贝
int *addr = (int*)&strtwo;
char*p = (char*)*addr;
*p = 'X';
AfxMessageBox(str);//cb中为 ShowMessage(str);
这时大家可以发现strtwo变成了Xhongguo这是正常的,然而再看str 却也变成了它。显然两者都是指向共同的数据区。原来,在vc和c++Builder中在处理字符串时,都进行了优化。当进行赋值操作时,并不进行真正的数据拷贝操作。而是使二者指向相同的数据区而已,并将该内存块的引用数加一。当对字符串单个操作等可能破坏其他用户的数据操作时,才检查它的引用数,以决定是否要拷贝一份数据。具体详细操作,要涉及c++Builder和 vc编译器的各自的内存管理方式了。其实这种处理技巧在许多地方随处可见。如动态链接库的调用,以及COM对象的实现等等。
还有一个是关于对数组进行delete和delete[]的差别,我认为至少在vc6.0和c++Builder5.0中(其它版本我也没有用过!),它们这两个操作时没有区别的,例如:
char * p= new char[100000];
//。。。它操作
delete p;// 和 delete p[]是等价的
我通过代码分析和例子测试两种途径,证实两者是一样的,然而我见到的所有资料上介绍都是说它们是不一样的,或许他们说的是c++标准规定,我也没有空去核查过,嘻嘻,毕竟饭碗要紧!
抛开代码分析,可以做个简单的测试。分别放两个按钮。处理代码如下:
一:
for (int i = 0 ; i < 100000 ; i++)
{
char * p= new char[100000];
delete p;
}
二:
for (int i = 0 ; i < 100000 ; i++)
{
char * p= new char[100000];
delete p[];
}
分别按下测试,可以通过任务管理器(或其他工具软件)两者的内存增加是一样的(可能是4k),这是在第一次new时系统分配的内存。这是windows内存分配委托所致的假象。都进行了内存释放!在vc下可以用CMemoryState类进行检测更方便,具体可以查看相关的msdn资料了。顺便说一下,由于vc在释放内存时,还要进行内存块清零等操作,所以在速度上远不及c++builder,就是发行版也还是无法和cb的调试版相媲美的。
这是我的一些发现,有不同看法的,欢迎与我交流!我的EMail:zlqzlqzlq@263.net