2014-03-05 52 views
-1

當我具有std::string一個去,我決定執行以下操作:C++ - 的std :: string ::〜串()串仍可以被打印爲空值

int main(int argc, char **argv) 
{ 
    std::string s = "Hello World"; 
    s.~basic_string(); 
    std::cout << s.c_str(); 
} 

然而,它打印什麼也沒有,並且沒有垃圾。然而,在我的basic_string類,當析構函數被調用時,我得到垃圾。 std::string如何處理這個問題? Mine使用allocatorconstruct s,destroy s,allocate s和deallocate s,但它仍然不起作用。

:我不是在尋找一個解決方案,以類,但要找出std::string是怎麼做的。

+13

你知道這是違法的,對嗎? – jrok

+0

@jrok - 然後呢? – Joseph

+7

未定義的行爲!你剛剛 – Paranaix

回答

5

首先,你不應該明確地調用析構函數,除非在很少的特定情況下,這不是其中之一。當字符串超出範圍時,析構函數將自動調用,這由標準保證。

其次,使用被破壞的物體時,除垃圾以外,你還期待什麼?這是應該避免的未定義行爲。如果你想限制範圍,那麼使用大括號,然後製作一個子範圍,並導致對象析構函數被調用,並清理事件。

int main(int argc, char **argv) 
{ 
    { // new scope 
     std::string s = "Hello World"; 
     std::cout << s; 
    } // s destructor called for you 

    // other stuff 
} 
0

這是未定義的行爲來調用其生存期已結束的對象的析構函數。 std::string有一個非平凡的析構函數,所以當它超出範圍時,它的生命週期已經結束。自動調用的析構函數應該導致一個雙重空閒錯誤。因爲它是未定義的行爲,所以沒有保證。

Does explicitly calling destructor result in Undefined Behavior here?涵蓋了這一點非常詳細。

-1

雖然它是未定義的行爲,因爲對象被摧毀,但我可以猜測幕後發生了什麼。

std::basic_string類型的對象爲空時,下列構造s [0]是有效的。例如:

std::string s; 

std::cout << s[0]; 

在這種情況下,該類返回對初始化爲零的char類型對象的引用。所以看起來這個類包含了一個char(0)值的數據成員。所以當一個內存沒有被分配的時候,當對象是空的時候,例如當調用c_str()時,該類返回指向這個數據成員的指針。

因此,釋放早期分配內存後的析構函數似乎將相應的指針設置爲NULL。當你調用函數c_str()時,它會檢查指針是否等於NULL。如果是,那麼它返回指向我所描述的數據成員的指針。

它可能是你正在尋找的解決方案。:)