2013-05-05 69 views
1

當我得到下面的代碼檢測的glibc有人可以解釋給我爲什麼雙重釋放或腐敗複製對象

#include<iostream> 
using namespace std; 
class Sample 
{ 
public: 
     int *ptr; 
     Sample(int i) 
     { 
      ptr = new int(i); 
     } 
     void PrintVal() 
     { 
     cout << "The value is " << *ptr<<endl; 
     } 
     ~Sample() 
     { 
      cout<<"CALLED\n"; 
      delete ptr; 
     } 
}; 
void SomeFunc(Sample x) 
{ 
    cout << "Say i am in someFunc " << endl; 
    x.PrintVal(); 
    //cout<<*(s1.ptr)<<endl; 
} 
int main() 
{ 
Sample s1=10; 
cout<<*(s1.ptr)<<endl; 
SomeFunc(s1); 
cout<<"HERE\n"; 
cout<<*(s1.ptr)<<endl; 
} 

這裏就調用cout<<*(s1.ptr)<<endl;檢測油嘴檢測偶數。我無法理解的是爲什麼即使當s1沒有調用desructor時,引用也會被刪除。

+7

由於沒有遵循[三條規則](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-reeree)的雙刪除。 – Mat 2013-05-05 19:49:05

+1

提拉克,你看到的錯誤信息說「像glibc檢測到[某些問題] ...」 - 這是你應該注意的問題,而不是「檢測到glibc」。 Glibc是檢測到問題的東西。 Glibc不是問題。 – Mat 2013-05-05 19:50:36

+0

是啊對不起它「./a.out:雙重免費或腐敗(fasttop)」這是什麼意思? – 2013-05-05 19:52:12

回答

6

問題是您沒有複製構造函數並且您有一個動態分配的成員數據。

void SomeFunc(Sample x) 

創建s1的新副本。並且xs1ptr s將指向相同的位置。一旦SomeFunc返回記憶被刪除的功能(當x被破壞。)

當主的回報s1被破壞。現在你的析構函數試圖對delete的內存位置已經刪除了而你有double free or corruption錯誤。


一個簡單的拷貝構造函數爲你的情況

Sample(const Sample& s) 
{ 
    ptr = new int(*(s.ptr)); 
} 

你真的不似乎這裏使用指針和動態分配。但是,如果您必須使用動態分配,請考慮查看Rule of threesmart pointers

+0

所以這兩個類的* ptr將指向int i的存儲位置嗎?或者,指針將指向哪裏? – 2013-05-05 19:56:20

+0

是的,謝謝很多人瞭解它:) – 2013-05-05 19:58:35

+1

@TilakRajSingh'x.ptr'和's1.ptr'將指向相同的確切位置。因爲當從's1'創建'x'時,指針的值被直接複製 – stardust 2013-05-05 19:58:37

0

對於包含需要在析構函數中釋放的資源的任何類,最好的做法是爲該類創建一個拷貝構造函數以及一個賦值運算符以避免這些問題。

也就是說,如果你已經聲明瞭函數需要一個const引用,那麼本來不需要複製,這也會更加有效。

void SomeFunc(const Sample &x) { 
    ... 
} 
相關問題