2015-05-20 38 views
3

當在Xcode運行以下C++代碼:的Xcode - 淺拷貝在STL串分配

std::wstring str1 = L"1111"; 
std::wstring str2 = str1; 

void* ptr1 = (void*)str1.c_str(); 
void* ptr2 = (void*)str2.c_str(); 

結果是,這兩個指針相等。這是標準嗎? 在Visual Studio中,情況並非如此。

+0

您使用的是哪種版本的Xcode?我在Mac上沒有得到這個結果與Xcode/clang。 –

+0

Xcode 6.3.1和C++方言gnu ++ 11(編譯器選項:-std = gnu ++ 11) –

+0

建議您使用-stdlib = libC++選項。這是一個更符合實施的規定,是新項目的默認設置。 –

回答

2

它看起來像執行使用寫入時複製(COW)的優化,其中一個字符串的內部狀態,只有真正在執行*寫操作設置。這在Pre-C++ 11實現中是允許的,但是我不認爲這是自C++ 11以來的標準。

請注意,您可以檢查,當你在一個非const的方式訪問字符串的基本指針的地址發生變化,即使不寫它:

str2[0]; 

這個表達式的計算應觸發寫操作會改變指針的地址。這是一個工作示例:

#include <string> 
#include <iostream> 

int main() 
{ 
    std::wstring str1 = L"1111"; 
    std::wstring str2 = str1; 

    std::cout << (void*)str1.c_str() << " " << (void*)str2.c_str() << std::endl; 

    str2[0]; // forces a write operation. c_str() changes. 

    std::cout << (void*)str1.c_str() << " " << (void*)str2.c_str() << std::endl; 
} 

在最近的gcc,這會產生

0x8a8e014 0x8a8e014 
0x8a8e014 0x8a8e03c 

*某些非const訪問可以觸發寫,即使他們沒有語義的變異字符串,如上例所示。

+0

我們正在使用gnu ++ 11方言,它與C++ 11不完全兼容,因此可能是這種情況。謝謝! –

+1

@OferB我不認爲gcc 4系列是符合標準的w.r.t. COW,即使在C++ 11或C++ 14模式下也是如此。至少在幾個月前我沒有最後一次檢查。 – juanchopanza