STL——STL中string的寫時拷貝機制

readyao發表於2016-03-25
string的寫時拷貝機制是為了提高效率。STL中許多類都採用了該機制(Copy-on-Write),該技術確實使STL的程式有著比較高的效率。
string類中有一個私有成員變數char *ch,該變數指向該類從堆上分配的記憶體,其在構造的時候分配記憶體,在析構的時候釋放記憶體。

寫時拷貝的意思是:在例子中string str1 = "linux_ever"; string str2 = str1;可以看到str1和str2中的指標變數指向相同的記憶體地址。當改變str的內容的時候才拷貝該物件。

從程式的輸出結果中看出:

string str1 = "linux_ever";執行完之後,str1物件的內容就是"linux_ever",會呼叫複製建構函式。

string str2 = str1;//執行完之後,會呼叫str2的複製建構函式,str2中的指標成員變數指向剛才str1中指向成員變數指向的記憶體單元。

當修改了str1的時候,就將str1的記憶體單元重新分配,將之前指向的記憶體單元中的記憶體拷貝過來,並修改相應的值。理所應當地,剛才的記憶體空間被str2單獨佔用了。所以接下來即使修改了str2的值,它的地址也沒有發生改變。


在第二個程式中,先修改了str2,所以就將str2的記憶體單元重新分配,將之前指向的記憶體單元中的記憶體拷貝過來,並修改相應的值。理所應當地,剛才的記憶體空間被str1單獨佔用了。所以接下來即使修改了str1的值,它的地址也沒有發生改變。


先修改str1,再修改str2:

/*************************************************************************
	> File Name: string_copy_on_write.cpp
	> Author: 
	> Mail: 
	> Created Time: 2016年03月25日 星期五 20時22分39秒
 ************************************************************************/

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;


int main()
{
    string str1 = "linux_ever";
    string str2 = str1;

    cout << "檢視str1和str2中內容指向的地址: " << endl;

    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    cout << "\n輸出兩個string物件的值之後的記憶體地址:" << endl;
    cout << "str1 = " << str1 << endl;
    cout << "str2 = " << str2 << endl;
    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    cout << "\n修改了str1之後的地址:" << endl;
    str1[0] = 'u';
    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    cout << "\n修改了str2之後的地址:" << endl;

    str2[0] = 'w';
    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    return 0;
}

輸出:



先修改str2,再修改str1:


/*************************************************************************
	> File Name: string_copy_on_write.cpp
	> Author: 
	> Mail: 
	> Created Time: 2016年03月25日 星期五 20時22分39秒
 ************************************************************************/

#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;


int main()
{
    string str1 = "linux_ever";
    string str2 = str1;

    cout << "檢視str1和str2中內容指向的地址: " << endl;

    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    cout << "\n輸出兩個string物件的值之後的記憶體地址:" << endl;
    cout << "str1 = " << str1 << endl;
    cout << "str2 = " << str2 << endl;
    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    cout << "\n修改了str2之後的地址:" << endl;
    str2[1] = 'u';
    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    cout << "\n修改了str1之後的地址:" << endl;

    str1[1] = 'w';
    printf("str1's address is %x\n", str1.c_str());
    printf("str2's address is %x\n", str2.c_str());

    return 0;
}
輸出結果:




相關文章