2016-04-13 47 views
1

我有類Egg,我有預定義的構造函數。這是我的經營者=和析構函數什麼樣子:我班上的破壞者做錯了? C++

Egg& Egg::operator=(const Egg& rhs) 
{ 
    if (this == &rhs) 
     return *this; 

    size = rhs.size; 
    name = rhs.name; 

    return *this; 
} 

Egg::~Egg() 
{ 

    size = 0; 
    delete[] name; 
} 

我想要做的是雞蛋,它每次我創建一個新蛋的動態數組,它延伸。下面是我如何做到這一點:

Egg* eggArr = NULL; 
void createEgg() 
{ 
    Egg * temp = eggArr; 
    eggArr = new (std::nothrow) Egg[eggsCnt + 1]; 

    if (!eggArr) 
    { 
     std::cerr << "No memory!\n"; 
     return; 
    } 

    for (size_t i = 0; i < eggsCnt; ++i) 
    { 
     eggArr[i] = temp[i]; 
     std::cout << eggArr[i].getName(); 
    } 



    eggArr[basketCnt].setName(eggsCnt, eggArr); 


    eggsCnt++; 
    delete[] temp; //problematic line 
} 

如果我刪除刪除[] temp,代碼完美工作,但有內存泄漏。 當它停留在程序中時,出於某種原因,我的eggArr也被破壞了,然後當我嘗試訪問它的某些成員時,它們是未定義的。問題在我的析構函數,運算符=還是其他地方?

+0

想一想'name = rhs.name;'的作用。這是否複製數據或只是一個指向數據的指針? – NathanOliver

+0

你正在做一個淺拷貝而不是深拷貝。你爲什麼使用'char []'而不是'std :: string'? –

回答

2

你有問題就在這裏:

Egg& Egg::operator=(const Egg& rhs) 
{ 
    name = rhs.name; 
    ... 
} 

Egg::~Egg() 
{ 
    ... 
    delete[] name; 
} 

Egg egg1, egg2; 
egg1 = egg2; 

你有name在兩個egg1egg2相同的值。當他們的破壞者將被調用時,它將被刪除兩次 - 這是一條直通地獄的路。

下面是另一個例子,稍微複雜一點:

Egg egg1; 
{ 
    Egg egg2; 
    egg2 = egg1; 
}   
std::cout << egg1.getName() << "\n"; 

在第二個例子中,一旦離開egg2它的範圍,name獲取的刪除 - 這是它與egg1共享相同的name。因此,egg1.getName()將嘗試使用已被刪除的指針,而這又是一些很好的程序不參與的事情。

您可能會遇到與您的拷貝構造函數相同的問題,並且遍及您的代碼,並且解決方案是停止對您的name進行任何操作,並將其作爲適當類型 - 根據名稱進行判斷, std::string似乎恰當。

+0

刪除兩次是不好的,但使用已被刪除的指針也是如此。 –

+0

@MarkRansom,當然 - 我只是試圖針對OP似乎正在發生的問題量身定製 - 但你是對的,最好還是強調一下。 – SergeyA

+0

@SergeyA所以我的理解是,當我使用=時,名稱指向相同的名稱,並且當我刪除它時,兩者都指向什麼? 我必須用它輸入的確切大小來命名,所以我想動態地做到這一點,不幸的是,我們還沒有學習std :: string,你能建議一些不同的東西嗎? :) – user5692938