2014-12-02 79 views
-1

這引發了分段錯誤。我的LinkedList賦值運算符有什麼問題?

LList<T>& LList<T>::operator=(LList s){ 

    LList<T> final_list; 
    final_list.head_ = s.head_; 
    Node<T> *f_curr_node = final_list.head_; 
    Node<T> *s_curr_node = s.head_; 

    for (int x=0; x<s.length();x++){ 
     f_curr_node->next_ = s_curr_node->next_; 
    } 

    return final_list; 
} 

我不明白爲什麼這是錯誤/如何解決它。

+0

提供一個[http://stackoverflow.com/help/mcve](http://stackoverflow.com/help/mcve)至少請。 – 2014-12-02 20:59:59

+1

也看到http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – 2014-12-02 21:00:43

+2

除了明顯的UB在下面的答案解釋,你有什麼使用該賦值運算符定義來實現?任何合理的賦值操作符都會使操作數與源對象保持相同的狀態,那麼爲什麼要在主體中創建新的對象實例,而不是分配當前實例的數據成員?你確定你想製作你分配的源對象的副本嗎? – Praetorian 2014-12-02 21:07:02

回答

4

您正在返回對局部變量的引用。只要操作符函數結束,該變量超出範圍並被破壞。如果有人試圖使用返回的內容,他將訪問未分配的內存。

在此修復程序之後,此代碼還存在其他許多問題,但這很可能是導致您崩潰的那個問題。

1

正如其他人所指出的那樣,你是返回到一個局部變量,這是不確定的行爲的參考。

既然你傳遞對象按值的賦值運算符,這表明你已經寫了一個工作拷貝構造函數和析構函數爲您鏈表類。如果複製構造函數和析構函數沒有工作或者沒有完成,那麼即使在return聲明之前,您的代碼也會被破壞。

但是,如果我們假設你的拷貝構造函數和析構函數來實現,工作,並沒有錯誤,這裏是寫你的賦值操作更簡單的方法:

LList<T>& LList<T>::operator=(LList s){ 
    std::swap(s.head_, head_); 
    std::swap(s.length, length); 
    // swap out any other members 
    return *this; 
} 

我不知道你的其他成員變量,所以你需要交換這些也。基本上,我們所做的只是將值傳遞給您的列表(同樣,如果您的拷貝構造函數正在工作,這隻能工作),並用當前對象替換s的內部。然後當s死亡(這就是爲什麼你必須有一個工作析構函數爲LList),它將與舊數據一起,而新數據位於this

然後我們回到*this,這是你應該在你首次嘗試已經返回,而不是一個局部變量的引用。

中查找copy/swap成語寫賦值運算符。