2012-06-03 54 views
2

我有一個非常簡單的一段代碼,有2個結構和一個動態分配。該程序崩潰的「數」初始化。C++動態分配程序崩潰

typedef struct{ 
    int key; 
    string name; 
} TElement; 

typedef struct nod { 
    int cheie; 
    string nume; 
    struct nod *stg, *dr; 
} NOD; 

當我嘗試這樣做

void ABC::inserare_element(TElement e){ 
    NOD *p, *q; 
    int n; 
    /* construction nod p*/ 
    n=sizeof (NOD); 
    p=(NOD*)malloc(n); 
    p->cheie = e.key; 
    p->nume = e.name; // on this line the program crashes 

感謝

+3

這是C++,你應該使用'new'。 – chris

+2

[相關](http://stackoverflow.com/questions/10857402/why-does-push-back-cause-crash-within-malloced-data/10857432#comment14143202_10857432)。 std :: string是否有構造函數運行?如果沒有,它不存在,你不能像它那樣分配給它。 – GManNickG

+1

你不需要C++中的'typedef'。只要命名你的結構 - 'struct NOD {/*..*/};' –

回答

7

malloc()不會調用的NOD構造,意味着nume構造函數將不會被調用導致企圖利用std::string::operator=未構建/未初始化std::string:使用new

+0

謝謝大家。有效 :)。 – vladCovaliov

+0

@ VladC不要忘記接受答案。 – moooeeeep

3

您應該使用new而不是malloc。 malloc是一個C函數,它只分配一塊內存。使用new將調用你的類的默認構造函數,此時也會調用字符串構造函數。

4

這裏有一些高級C++對象,如std::string和C風格的內存分配,如malloc。事情是,C++的new運算符不僅分配內存,還調用高級對象的構造函數。您遇到的問題是numestd::string類型的對象未正確初始化,因此您遇到導致崩潰的未定義行爲。那是因爲你很幸運。如果程序真的在工作,那可能會更糟糕,但會產生奇怪的,意想不到的結果。

要使它像你想要的那樣工作,你可以簡單地使用new而不是malloc。例如:

p = new NOD; 

如果恰巧你真的需要使用malloc或不關心C++對象的其他內存管理API,那麼你必須手動調用nume構造,使用放置新。例如:

p = (NOD*)malloc(n); 
new ((void *)&p->nume) std::string(); 

如果你這樣做 - 不要忘記調用析構函數,否則最終會發生內存泄漏。