如果我在函数中使用指针来填充列表,我是不是必须在 C++ 中删除该函数末尾的指针?

Posted

技术标签:

【中文标题】如果我在函数中使用指针来填充列表,我是不是必须在 C++ 中删除该函数末尾的指针?【英文标题】:If I use a pointer in a function to populate a list, do I have to delete that pointer at the end of the function in c++?如果我在函数中使用指针来填充列表,我是否必须在 C++ 中删除该函数末尾的指针? 【发布时间】:2020-11-07 18:04:45 【问题描述】:

如果我在函数中使用指针来填充列表,我是否必须在函数末尾删除该指针,否则列表的析构函数将在 c++ 中完成工作?

例如:

void populateList() 
  Human* human;
  List<Human> myList;

  for (int i = 0; i < 5; ++i) 
    human = new Human();
    myList.push_back(*human);
  

我应该删除函数末尾的指针,还是不需要它,因为它不是内存泄漏?

【问题讨论】:

除了myList.push_back(Human);,您希望通过所有这些麻烦来完成什么?而且,是的,这是内存泄漏。这是一种非常常见的内存泄漏,它甚至有一个名字:“无意义地使用指针”。 你为什么在这里使用指针? 在编写代码时,您必须在 循环 结束时将其删除。规则很简单,每次你new你也必须delete。因此,由于每次循环都有一个新的,因此每次循环也需要一个删除。但正如其他人所说,根本不需要使用 new 或指针。是什么让您认为必须使用指针?好像是新手病,到处用指针。 手动管理内存乍一看很复杂,其实很简单。您需要记住的是:对于 0 news,您恰好需要 0 deletes。其他任何东西都是(潜在的)泄漏 @cigien 当我找到它时,我会记住的 【参考方案1】:

在这一行:

myList.push_back(*human);

您正在制作human 指针指向的动态分配对象的副本,因此myList 析构函数只会清理该副本。您确实需要手动释放 human 指向的动态分配的内存,以避免泄漏该内存。

但是,在这种情况下,似乎根本没有理由使用new 动态分配内存。您可以创建一个本地 Human 并将其添加到 myList。那么内存泄漏就没有问题了,因为 是没有动态分配的,所有的对象在超出范围的时候都会被正确的清理掉。

【讨论】:

【参考方案2】:

这里不需要使用指针,你可以简单地这样做:

void populateList() 
  List<Human> myList;

  for (int i = 0; i < 5; ++i) 
    Human human; //if the constructor of human creates the same thing every time, you could also put this line before the for loop
    myList.push_back(human);
  

在 C++ 中声明一个变量也会构造它。

您所做的是创建一个指针,而不是创建一个 Human 的新实例并将指针指向该实例。比基本上将其复制到列表中,因为您只是给列表一个副本。即使您愿意,它也无法删除您的指针,因此您应该删除您的人类实例。如果你坚持使用指针,你应该这样做:

void populateList() 
  Human* human;
  List<Human> myList;

  for (int i = 0; i < 5; ++i) 
    human = new Human();
    myList.push_back(*human);
    delete human;
  

【讨论】:

以上是关于如果我在函数中使用指针来填充列表,我是不是必须在 C++ 中删除该函数末尾的指针?的主要内容,如果未能解决你的问题,请参考以下文章

lambda 是不是应该衰减为模板代码中的函数指针?

函数指针是否使程序变慢?

在预订(基础)中将BST转换为DLL

指针函数与函数指针

C++成员函数指针指向全局函数指针

无法使用Realm对象填充TableView