2012-04-04 113 views
2

所以我很好奇下面的代碼崩潰的原因。 會感謝您的幫助。你能告訴我爲什麼這段代碼崩潰了?

#include <iostream> 
using namespace std; 

class temp 
{  
    public: 

    temp(int i) 
    { 
     intPtr = new int(i); 
    } 

    ~temp() 
    { 
     delete intPtr; 
    } 

    private: 
    int* intPtr; 
}; 

void f (temp fInput) 
{ 
    cout << "f called" << endl; 
} 

int main() 
{ 
    temp x = 2; 
    f(x); 
    return 0; 
} 
+1

你能定義「崩潰」嗎? – josephthomas 2012-04-04 21:18:44

+0

@ Ed S:但是,我同意,有時候我們認爲的崩潰可能與他認爲的崩潰不同。 – josephthomas 2012-04-04 21:23:02

+0

@josephthomas:是的,我想到了很多,這就是爲什麼我發佈後不久就刪除了我的評論:)我們可以就術語的正確使用達成一致......是否大多數初學者會正確使用它是另一個問題 – 2012-04-04 21:23:41

回答

5

當x被傳遞(隱式拷貝構造)和析構函數被調用兩次(在函數返回之前和前主退貨)的指針被複制,因此,存儲器被刪除的兩倍。

使用std::shared_ptr<int>這裏,而不是代替原始INT指針(假設你想要的行爲是相同的,即引用來自temp相同的S int;否則,執行拷貝構造函數,將構造函數和賦值操作符自己)。

#include <memory> 

class temp {  
public: 
    temp(int i) : intPtr(std::make_shared<int>(i)) { 

    } 

private: 
    std::shared_ptr<int> intPtr; // reference counting ftw 
}; 
+0

或者只是正確地實現類開始(即正確的複製語義等) – 2012-04-04 21:22:30

+0

這也是可能的,這取決於你想要的行爲。 – 2012-04-04 21:23:25

+0

....正確的行爲總是可取的。 – 2012-04-04 21:24:05

5

由於您通過的方式發生崩潰x

f函數的範圍x的結構將被調用並將刪除intPtr

但是,這將刪除仍在範圍內的存儲器main。因此,在調用return 0之後,它將嘗試刪除已存在的內存,因爲您在同一個指針上調用了兩次刪除操作。

要修正這個錯誤,改變

void f (temp fInput) 

void f (const temp& fInput) 

或者,你可以考慮使用一個std::shared_ptr

+0

添加一個拷貝構造函數和賦值操作符也是一個好主意。你也可以使用std :: shared_ptr而不是原始指針,因爲它負責複製語義。 – 2012-04-04 21:25:10

+0

我同意,我想讓海報知道一個解決方案,以最小的努力幫助他。有很多方法可以解決這個崩潰。 – josephthomas 2012-04-04 21:27:43

5

您違反了The Rule of Three

你保持一個指針成員,你傳遞對象的副本功能f。所以,最終的結果是你在相同的指針上調用delete兩次。

1

您在這裏遇到的問題是雙重刪除。因爲你沒有定義任何拷貝構造函數,所以C++很高興爲你做。該實現通過執行所有內容的淺表副本來完成。

f(x); 

該行通過創建的x副本,並將其傳遞給f。此時有2個temp實例,它們擁有一個intPtr成員。這兩個實例都將刪除該指針,這可能是導致您崩潰的原因。

要解決這一點,你可以採取一些步驟

  1. 使用意味着共享像shared_ptr<T>
  2. 指針類型創建uncallable拷貝構造函數強制實例由參傳遞

的#2的一個例子是

class temp { 
    temp(const temp& other); 
    temp& operator=(const temp& other); 
public: 
    // Same 
}; 

現在f(x)行根本無法編譯,因爲它無法訪問必要的拷貝構造函數。它迫使它重新定義f以防止複製。

void f(const temp& fInput) { 
    ... 
} 
相關問題