我必须使用delete来避免内存泄漏吗?我使用new来分配结构实例

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

本文关键字:实例 new 结构 分配 delete 内存 泄漏      更新时间:2023-10-16

下面的代码实现了一个简单的哈希函数。我已经用new操作符分配了结构体实例。

当程序结束时,我必须使用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(或对数组执行delete[])。

如果你使用的是linux, valgrind可以帮助你检测内存泄漏。

最新版本的c++,以及Boost库,提供了各种智能指针,当对象不再被引用时,这些指针基本上会自动释放内存。

查找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做了很多复制,当你与容器的中间。但是它非常适合缓存