2016-04-16 41 views
1

我一直無法理解C++中的刪除和刪除[]函數。這是我目前所知:C++ - 需要幫助理解刪除功能

aClass *ptr = new aClass(); //Allocates memory on the heap for a aClass object 
           //Adds a pointer to that object 
... 
delete ptr;     //ptr is still a pointer, but the object that it 
           //was pointing to is now destroyed. ptr is 
           //pointing to memory garbage at this point 
ptr = anotehrOjbectPtr   //ptr is now pointing to something else 

在出現這種情況的話,

aClass *ptr new aClass(); 
... 
ptr = anotherObjectPtr 

該指針指着,現在失去了在內存中的對象,ADN這將導致內存泄漏。該對象應該先被刪除。

希望以上是正確的

但是我寫了這個小程序,在那裏我得到一些意外的行爲

#include <iostream> 
#include <string> 
using namespace std; 

class Database { 
    private: 
     Database() { 
       arrNames = NULL; 
       capacity = 1; 
       size = 0; 
     } 
     Database(const Database &db) {} 
     Database &operator=(const Database &db) {} 
     string *arrNames; 
     int capacity, size; 
    public: 
     static Database &getDB() { 
       static Database database; 
       return database; 
     } 
     void addName(string name) { 
       if (arrNames == NULL) { 
        arrNames = new string[capacity]; 
       } 
       if (size == capacity - 1) { 
        capacity *= 2; 
        string *temp = new string[capacity]; 
        int i = 0; 
        while (i <= size) { 
         temp[i] = arrNames[i]; 
         i++; 
        } 
        delete [] arrNames; 
        arrNames = temp; 
       } 
       arrNames[size] = name; 
       size++; 
      } 
      void print() { 
       int i = 0; 
       while (i <= size) { 
        cout << arrNames[i] << endl; 
        i++; 
       } 
      } 
}; 

int main() { 
     Database &database = Database::getDB(); 
     Database &db = Database::getDB(); 
     Database &info = Database::getDB(); 

     database.addName("Neo"); 
     db.addName("Morpheus"); 
     info.addName("Agent Smith"); 

     database.print(); 
     db.print(); 
     info.print(); 
} 

在addName功能,當我打電話刪除[] arrNames,什麼我認爲正在發生的事情是與當前數組arrNames關聯的內存被銷燬,所以arrNames現在指向垃圾,然後arrNames被指向指向temp指向的內存中的另一個位置。所以如果我沒有調用delete [] arrNames,那麼內存中的那個位置就會失效,導致內存泄漏。但是,當我將該行註釋掉時,代碼仍然沒有問題。我在這裏沒有理解什麼嗎?

遺憾,這對這麼久 感謝HALP

+1

當你註釋掉哪一行?不刪除某些內容不會使任何內容失效,它只是泄漏內存 - 在不應該的時候保持有效。 –

+0

*代碼仍然可以正常工作* - 存在問題。您創建了一個未被發現的內存泄漏。 – PaulMcKenzie

+0

內存泄漏是指已分配的內存,但程序中沒有指針指向它。如果你的代碼在其他方面行爲恰當,那麼在你的程序中使用指針就可以正常工作。內存泄漏的問題在於,最終分配將開始失敗,您將無法釋放泄漏的內存來防止這種情況發生。 – Peter

回答

1

內存泄漏不涉及任何被無效。恰恰相反,這是一個失敗的內存位置無效,導致它仍然在使用,即使它不應該。

3

從我認爲在代碼中看到的看起來addName()是爲了將新名稱追加到動態數組上。自己這樣做可能會導致頭痛,並且現在有一個方便的STL模板,我強烈建議從<vector>標頭中調用vector。 如果添加#include <vector>和更改string *arrNamesvector<string> arrNames,那麼你的整個addName()功能,可以簡化爲:

void addName(string name){ 
    arrNames.push_back(name); 
} 

vector.size()方法,你可以確定向量的當前長度,以及,你的成員capacitysize不再需要。

4

但是,當我註釋掉該行時,代碼仍然沒有問題。我在這裏沒有理解什麼嗎?

關於編程知道一件重要的事情是,正確地做事不僅僅是讓事情顯然工作的問題。

很多時候,你可以嘗試一些事情,看起來有什麼作用,但隨後一些外部環境會改變,你沒有明確控制或考慮的事情,並且事情停止工作。例如,您可能會編寫一個程序,並在您的計算機上運行查找,然後嘗試將其演示給某人,併發生在計算機上運行該程序,並且程序崩潰。這個想法是程序員之間玩笑的基礎:「它適合我。「

所以事情可能會出現的工作,但爲了知道,當條件發生變化,你必須滿足更高標準的東西會更加。

你已經被告知如何正確地做事情delete,但這並不一定意味着如果你不這樣做,事情將會以明顯的方式破裂,你需要放棄這樣的想法,即你可以通過試驗確定是否正確。

1

首先,當你有某種東西的時候,你並沒有在內存中摧毀它,而只是將它提供給所有人ocation。這有點類似於文件系統 - 當你刪除文件時,你只是說它佔用的空間現在可用於一些新的數據。在您調用delete之後,您實際上可以檢索未修改的數據,但這是未定義的行爲,並且是編譯器/操作系統特定的。

如果你不是delete[] arrNames,你會將其數據遺忘在你的進程內存中,並造成內存泄漏。但除了這個致命的缺陷之外,沒有更多的魔法發生。