2012-01-29 82 views
2

這是我無法理解。 比方說,我重載operator &製造和和兩個對象,和運營商之間=進行分配(使對象的副本)。 讓我們假設我有一個命名爲A類,而這個代碼:運營商超載:內存泄漏

A a1,a2,a3; 
// initialize a1,a2,a3 
a1=a2&a3; 

如果A1已經分配的,當我A1分配對a2 & A3,有內存泄漏? 是在不刪除舊對象的情況下創建的新對象?

PS:運營商使用A型的兩個參數,重載(我還沒有定義的類A,這是一個例子),返回類型A的參數,被定義爲類的朋友。

代碼:

這是一個很長的代碼,所以我用引擎收錄: http://pastebin.com/42TnThfC 但因爲它是很長,我也張貼了最有意義的部分:

template<class T> 
List<T>& List<T>::operator= (List<T>& l) 
{ 
    List<T>* ptr=l.next; 
    if(this!=&l) 
    { 
     resize(0); 
     while(!ptr->end) 
     { 
      push(ptr->info); 
      ptr=ptr->next; 
     } 
    } 
    return *this; 
} 

template <class T> 
List<T>& operator& (List<T>& l1, List<T>& l2) throw() 
{ 
    List<T>* temp,*ptr=l1.next; 
    temp=new List<T>(); 
    try 
    { 
     if((l1.end)^(l2.end)) 
      throw excp1; 
    } 
    catch (char *s) 
    { 
     cout << "Exception: "<<s<<endl; 
    } 
    if(l1.end) 
    { 
     while(!ptr->end) 
     { 
      if(l2.in(ptr->info)) 
       temp->push(ptr->info); 
      ptr=ptr->next; 
     } 
    } 
    else 
    { 
     if(l1.info==l2.info) 
      temp->push(l1.info); 
    } 
    return *temp; 
} 

這是一個列表,推推動的物品,主要的例子:

int main(int arcg, char **argv) 
{ 
    List<T>l1,l2,l3; 
    for(int i=0;i<10;i++) 
    { 
     l1.push(i); 
     l2.push(i); 
     l3.push(i); 
    } 
    l3=l1&l2; 
} 

這種情況L3已經L1 & L2,但無線這會導致內存泄漏?

+1

我們需要更多的代碼。像賦值運算符和&運算符一樣能夠幫助您。 – 2012-01-29 17:57:32

回答

2

不,應該罰款。原來的a1將被銷燬並換成新的(這是a2 & a3的結果)。

但是你應該確保,如果A包含指針,拷貝構造函數,賦值操作符和析構函數是否正確爲該類型定義,否則「原a1將被摧毀」可能還不夠!

0

在A級,賦值運算符必須刪除原始數據

class A { 
    A &operator=(const A &orig){ 
     if(&orig == this){ 
      return *this; 
     } 

     // here 
     if(data){ 
      delete []data; 
     } 

     // copy original data 
    } 
} 
+0

錯過了爲自己分配的檢查,應該在刪除之前進行復制。 – Lalaland 2012-01-29 17:59:59

+0

@EthanSteinberg謝謝,錯過了。這是好的還是你有更好的主意? – Vyktor 2012-01-29 18:01:40

+0

爲什麼不好的複製和交換超載'='? – 2012-01-29 18:02:26

0

我相信只有一個內存泄漏,如果你這樣做:

A *a1 = new A(1); 
a1 = a2 & a3; // Don't do this, it doesn't work 

只要有一個A1,A2 ,a3;如果你宣佈他們是這樣的話,這是不可能的。該函數在調用函數時爲這些對象靜態分配空間,並且在函數完成執行時(在彈出堆棧期間)它們會自動釋放。

+0

雖然不會編譯。你會做'* a1 = a2 &a3;'這是合法的。 – David 2012-01-29 18:06:50

0

賦值運算符的職責是,就在左側相同的右手邊的一個對象。如果它分配了內存,並且正在用右邊的東西來替換內存,那麼它會釋放內存。在一般情況下,我發現它最容易實現的拷貝構造函數方面的賦值操作符和swap()成員函數:

T& operator= (T const& other) { 
    T(other).swap(*this); 
    return *this; 
} 

swap()成員函數只是做一個按成員交換。

+1

我認爲'other'應該是通過副本進行復制和交換的。 – 2012-01-29 18:03:55

+0

@Als:不;他明確創建了一個副本。 'T(其他)' – 2012-01-29 18:04:51

+0

**應該做的**是通過'const'傳遞'other'!我會解決這個問題。按價值傳遞應該是有效的,並且避免需要明確的副本和副手,我不記得爲什麼我通常不這樣做(儘管如此,也許這只是我應該修復的錯誤習慣)。 – 2012-01-29 18:08:45