簡體   English   中英

是否必須使用Delete以避免內存泄漏? 我已經使用new來分配結構實例

[英]Do I have to use delete to avoid memory leaks? I have used new to allocate the structure instances

以下代碼實現了一個簡單的哈希函數。 我已經用new運算符分配了struct實例。

程序結束時是否可以使用delete運算符?

如果是這樣,我該怎么辦? [針對該結構的每個實例的delete語句? 還是有一種更簡單的方法? ]

#include <iostream>
#define SIZE 10

using namespace std;

typedef struct myhashtag
{
   int data;
   struct myhashtag * next;
} myhash;
void printhash(myhash array[])
{
// print fn
}

void hash(int data, myhash array[])
{
   int h = data % SIZE;
   myhash * newhash = new myhash;
   newhash->data = data;
   newhash->next = NULL;

   if(array[h].next == NULL)  //first insert
   {
      array[h].next = newhash;
      return;
   }
   myhash * iter = array[h].next;
   while(iter->next != NULL)
   {
      iter = iter->next;
   }
   iter->next = newhash;
   return;
}


int main()
{
   myhash array[SIZE];int i;
   for(i=0; i<SIZE; i++)
   {
      array[i].data = 0;
      array[i].next = NULL;
   }

   while(1)
   {
      cout << "\nSo, what would you like to enter? : ";
      cin >> i;
      hash(i, array);
      printhash(array);
   }

// the deletes go here 

   return 0;
}

通常,對於每個帶有new的分配,您確實確實需要執行一次刪除(或對數組執行delete [])。

如果您使用的是Linux,那么valgrind可以幫助檢測內存泄漏。

C ++的最新版本以及Boost庫提供了各種智能指針,當不再引用該對象時,它們基本上將自動釋放內存。

在您選擇的C ++書中查找std :: unique_ptr。

是的,您應該始終刪除分配的任何動態內存。

您可以實現一個簡單的RAII容器來處理內存清理。 只需創建一個類以充當句柄,即可在其構造函數中通知內存。 將其刪除在其析構函數中,並提供某種訪問機制。 這樣,將在聲明句柄的作用域末尾自動清除所有內存。

C ++確實要求您管理對象的生存期。 它不像許多Java或C#書籍可能會讓您相信的那么難。 但是,是的,在不使用垃圾回收器的情況下 ,您需要確保正確調用delete

我可以想象有兩種方法可以對您發布的代碼執行此操作。 正如其他人所建議的,第一種是使用std::unique_ptr

第二個是給您的struct一個析構函數。 我不太清楚為什么您要使用經典的C typedef struct ...慣用語(在C中這樣做是為了不必經常使用struct關鍵字,但不必使用struct關鍵字就像在C ++中一樣)。 我將其保留在下面的代碼中,但我想將其標記為非慣用語:

typedef struct myhashtag
{
   int data;
   struct myhashtag * next;

   ~myhashtag()
   {
      if (next) {
         delete next;
      }
   }
} myhash;

(您仍然需要確保delete放置“在此處發生刪除”的注釋的頭節點)。

但是,這假定在列表末尾將next正確分配給NULL 您發布的代碼可以做到這一點,但這僅是按慣例執行的。 較為慣用的方法是:

struct hash_node {
   int data;
   hash_node* next;

   hash_node(int d, n = NULL) : data(d), next(n) { }

   ~hash_node()
   {
      if (next) {
         delete next;
      }
   }
};

void hash(int data, hash_node* array)
{
   int h = data % SIZE;
   hash_node* newhash = new hash_node(data);

   if(array[h].next == NULL)  //first insert
   {
      array[h].next = newhash;
      return;
   }
   hash_node* iter = array[h].next;
   while(iter->next != NULL)
   {
      iter = iter->next;
   }
   iter->next = newhash;
   return;
}

更為慣用的方法是:

#include <list>
#include <iostream>
using namespace std'

int main()
{
    list<int> list_that_the_code_was_calling_a_hash;
    while(1) {
        cout << "\nSo, what would you like to enter? : ";
        cin >> i;
        list_that_the_code_was_calling_a_hash.push_back(i);
        if (list_that_the_code_was_calling_a_hash.size() > 10) {
            list_that_the_code_was_calling_a_hash.pop_front();
        }
        printhash(list_that_the_code_was_calling_a_hash);
    }
    return 0;
}

許多人會建議使用std::vector因為std::list根本無法與您的CPU緩存良好地交互。 是的,當您在容器中間進行裝填時, std::vector會進行更多復制。 但是通過非常友好的緩存,它可以彌補以上不足。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM