當在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中,情況並非如此。
當在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中,情況並非如此。
它看起來像執行使用寫入時複製(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訪問可以觸發寫,即使他們沒有語義的變異字符串,如上例所示。
我們正在使用gnu ++ 11方言,它與C++ 11不完全兼容,因此可能是這種情況。謝謝! –
@OferB我不認爲gcc 4系列是符合標準的w.r.t. COW,即使在C++ 11或C++ 14模式下也是如此。至少在幾個月前我沒有最後一次檢查。 – juanchopanza
您使用的是哪種版本的Xcode?我在Mac上沒有得到這個結果與Xcode/clang。 –
Xcode 6.3.1和C++方言gnu ++ 11(編譯器選項:-std = gnu ++ 11) –
建議您使用-stdlib = libC++選項。這是一個更符合實施的規定,是新項目的默認設置。 –