string/wstring是basic_string模板的两个具体的应用,是c++模板库中的精华,我作为一个c++程序员,也特别喜欢这两个类。c++标准要求对于string/wstring的实现,必须支持数据共享。也就是说,对于同一个数据,不同的string/wstring对象必须共享它,如下图所示:
+-----------------------------+ ptr
|string/wstring Object1|------------+
+-----------------------------+ | heap
+-----------------------------+ ptr | +----------------+
|string/wstring Object2|------------+----->| "I like string" |
+-----------------------------+ | +-----------------+
+-----------------------------+ ptr |
|string/wstring Object3|------------+
+-----------------------------+
对于在堆中数据何时被释放,是通过引用计数来实现的,当计数为0时,delete【】将会被调用,以便内存的释放。当然,如果其中某个string/wstring的对象要对数据进行写操作,那么新的内存对象将创建使用,老的内存对象的引用计数将被减少。在下面的演示代码中,我们能够看到这种情况。
这种引用技术对于节约内存时非常出色的,但是同时也带了一些负作用。比如,在多线程的环境中,如果对于引用技术的增减不同步的话,带来的后果是很严重的,程序轻着是内存泄漏,重着是崩溃。可能有网友会问,为什么c++标准不提供一个安全的string/wstring呢?我觉得,主要原因可能有两个:
1)降低了移植性,因为在不同的平台,同步的实现方法或者名称是不同的,如果强制加入同步操作,就是牺牲c++程序的移植性。而标准c++程序是平台无关的,这个和它背道而驰。
2)使用同步所带来的性能负担,比如说,一个对于int的++操作,通常状态下只需要几个总线周期,但是在同步情况下,它起码是几百个甚至是几千个总线周期,对于一向关心效率的c++而言,可能是不可忍受的。
总子,如果编写的程序是在多线程的环境中,有不希望自己在实现代码的过程中对于string/wstring的使用战战兢兢的话,那么就不要使用他们。让原始的char和wchar复苏吧,虽然带了操作的诸多麻烦,但是毕竟能使自己睡的心安:—)。当然如果情况特殊的话,我们不妨使用std::vector<char/wchar>来替代string/wstring,自动管理内存的分配和释放,毕竟是我们最求的,难道不是吗?!
#include <iostream>
#include <string>
using namespace std;
int main( void )
{
string a( "I like string" );
string b = a;
string c = "I like string";
string d = a.c_str();
cout << "See a and b: ";
if ( a.c_str() == b.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "See a and c: ";
if ( a.c_str() == c.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "See a and d: ";
if ( a.c_str() == d.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "See c and d: ";
if ( c.c_str() == d.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "Modify b" << endl;
b = "I like string";
cout << "See a and b again: ";
if ( a.c_str() == b.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
return 0;
}
+-----------------------------+ ptr
|string/wstring Object1|------------+
+-----------------------------+ | heap
+-----------------------------+ ptr | +----------------+
|string/wstring Object2|------------+----->| "I like string" |
+-----------------------------+ | +-----------------+
+-----------------------------+ ptr |
|string/wstring Object3|------------+
+-----------------------------+
对于在堆中数据何时被释放,是通过引用计数来实现的,当计数为0时,delete【】将会被调用,以便内存的释放。当然,如果其中某个string/wstring的对象要对数据进行写操作,那么新的内存对象将创建使用,老的内存对象的引用计数将被减少。在下面的演示代码中,我们能够看到这种情况。
这种引用技术对于节约内存时非常出色的,但是同时也带了一些负作用。比如,在多线程的环境中,如果对于引用技术的增减不同步的话,带来的后果是很严重的,程序轻着是内存泄漏,重着是崩溃。可能有网友会问,为什么c++标准不提供一个安全的string/wstring呢?我觉得,主要原因可能有两个:
1)降低了移植性,因为在不同的平台,同步的实现方法或者名称是不同的,如果强制加入同步操作,就是牺牲c++程序的移植性。而标准c++程序是平台无关的,这个和它背道而驰。
2)使用同步所带来的性能负担,比如说,一个对于int的++操作,通常状态下只需要几个总线周期,但是在同步情况下,它起码是几百个甚至是几千个总线周期,对于一向关心效率的c++而言,可能是不可忍受的。
总子,如果编写的程序是在多线程的环境中,有不希望自己在实现代码的过程中对于string/wstring的使用战战兢兢的话,那么就不要使用他们。让原始的char和wchar复苏吧,虽然带了操作的诸多麻烦,但是毕竟能使自己睡的心安:—)。当然如果情况特殊的话,我们不妨使用std::vector<char/wchar>来替代string/wstring,自动管理内存的分配和释放,毕竟是我们最求的,难道不是吗?!
#include <iostream>
#include <string>
using namespace std;
int main( void )
{
string a( "I like string" );
string b = a;
string c = "I like string";
string d = a.c_str();
cout << "See a and b: ";
if ( a.c_str() == b.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "See a and c: ";
if ( a.c_str() == c.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "See a and d: ";
if ( a.c_str() == d.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "See c and d: ";
if ( c.c_str() == d.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
cout << "Modify b" << endl;
b = "I like string";
cout << "See a and b again: ";
if ( a.c_str() == b.c_str() )
cout << "Share memory" << endl;
else
cout << "Unshare memory" << endl;
return 0;
}