2013-12-08 39 views
2

在分割故障下面的代碼結果時,它的運行,我想不通爲什麼:分段故障在一個結構分配的std :: string

#include <cstdlib> 
#include <string> 
#include <iostream> 


using namespace std; 

struct Token 
{ 
    int num; 
    string val; 
}; 


int main() 
{ 
    Token* tok = (Token*) malloc (sizeof(Token)); 
    tok -> val = "myval"; 
    std::cout<<tok->val; 
} 

看到回溯:

0 0x00007ffff7b95d9b in std::string::assign(char const*, unsigned long)() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6; 
1 0x0000000000400867 in main() 
+1

一個問題:什麼是使用的原因動態分配在這裏?如果你沒有很好的答案,那麼你不應該使用它。 – juanchopanza

回答

8

不要在C++代碼中使用malloc,它很少是正確的選擇。

的選項有:

Token tok; 
tok.val = "myval"; 

auto tok = std::make_unique<Token>(); // C++14 
tok->val = "myval"; 

auto tok = std::unique_ptr<Token>(new Token()); // C++11 
tok->val = "myval"; 

auto tok = std::make_shared<Token>(); // C++11, use if resource is shared 
tok->val = "myval"; 

Token* tok = new Token(); 
tok->val = "myval"; 
delete tok; 

這些選項應該能滿足大多數情況下。

傾向於從上到下的選項:默認的方式應該是創建對象,然後unique_ptr,然後shared_ptr,只有在絕對必要時,你應該處理原始指針。

原因很簡單:異常安全和內存泄漏。一個對象不能泄露,你不能忘記delete a unique_ptrshared_ptr,但你可以用一個原始指針。另外,如果發生異常,原始指針不會被刪除。 unique_ptr應該被優先考慮爲shared_ptr,因爲shared_ptr有開銷(一個原子計數器使它安全)。

演示,一切編譯罰款(不包括C++ 14 make_unique):Demo

6

malloc不會調用任何構造函數。嘗試使用new,它應該工作正常。

也不要忘記delete它之後,或者使用智能指針或直接把變量放在堆棧上。

+2

和'delete'用於釋放內存 – P0W

+2

或者只是自動實例化對象。 – juanchopanza

4

Here's why you cannot use malloc with std::string

你不能用malloc的非平凡的構造函數的類在C++。你從malloc中得到的是一塊原始的內存,它不包含一個正確構造的對象。 任何使用該內存作爲 「真實」對象的嘗試都將失敗。

除了(已經在其他的答案中指出):

的問題是,malloc不調用示例的構造。 由於字符串通常表示爲堆棧上的指針,因此將此 設置爲零,並且您將取消引用空指針。您需要使用新的 。

如果你堅持使用malloc,您可以使用放置新的(見鏈接瞭解詳細信息),或只是使用普通的醇」 const char*

struct Token 
{ 
    int num; 
    const char* val; 
}; 

int main() 
{ 
    Token* tok = (Token*) malloc (sizeof(Token)); 
    tok->val = "myval"; 
    std::cout << tok->val; 
    free(tok); 
} // will not seg fault 
+1

對這種情況使用'char *'是一個非常糟糕的主意。然後您必須手動管理內存。 –

+0

@Ivan你能否詳細說明一下? – 2013-12-08 11:10:42

+0

'char *'只是一個指針 - 你仍然必須分配它將指向的內存,然後根據需要釋放它。 出於同樣的原因,你不能只寫'Token * tok;'並期望它是一個功能完整的對象。 –