从main函数中删除在另一个函数中使用new创建的一系列对象

时间:2017-06-30 16:00:40

标签: c++ pointers new-operator delete-operator

我遇到了一段使用new在函数中分配动态内存的代码,然后在main函数中调用此函数。我怀疑有一些内存泄漏问题,但我不确切知道如何解决它。以下代码已简化以演示此问题:

#include <iostream>
#include <vector>

using namespace std;

 // Definition for singly-linked list.
 struct ListNode {
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
 };

ListNode* createList(void);

int main(){
    ListNode* my_list = createList();
    //... some code 

    //  how to delete those objects created by new?
    return 0;
}

ListNode* createList(void) {

    ListNode preHead(0), *p = &preHead;
    vector<int> sum = {1, 2, 3, 4, 5};

    for (decltype(sum.size()) i = 0; i != sum.size(); i++){
        p->next = new ListNode(sum[i]);
        p = p->next;
    }

    return preHead.next;
}

如果我理解正确,函数createList()会创建一个包含6个ListNode对象的列表。 除了列表中的第一个对象(preHead)之外,其他5个对象都是动态的 使用new分配。最后,函数createList()返回指向列表中第二个对象的指针, 这是一个指向动态内存的指针。

我的问题是:

  1. my_list是指向动态内存的正常指针还是指针?我们如何确定my_list的类型。例如,如果我编写以下代码

    ListNode l1(2);ListNode* my_list = &l1;

  2. 然后my_list将成为ListNode对象的普通指针。这两种情况之间有什么区别?

    1. 列表中的最后5个对象是使用new创建的,如何在使用列表后在main()中删除它们?我是否必须遍历列表并从列表末尾开始删除,直到所有动态创建的对象都被删除?

    2. 如果是这种情况,我认为这将是麻烦和不方便的。如何在仍然返回指向ListNode对象的指针的情况下改进createList()

2 个答案:

答案 0 :(得分:1)

同意上述使用std :: list的建议,我想添加以下内容: Q1)你在哪里看到“普通指针”和“动态内存指针”之间的区别?指向x的指针是指向x的指针。您应该知道是否删除它。 Q2)你要么做你的建议(从最后删除)或

void clearList(ListNode* p) { 
  ListNode* nextP; 
  while (p != NULL) {
    nextP = p.next;
    delete p;
    p = nextP;
  }
}

答案 1 :(得分:1)

  

my_list是一个正常的指针还是指向动态内存的指针?

你的指针是一个指针,它是一个指向内存的变量,指向动态分配的内存的指针或不指向内存的指针之间确实没有区别。唯一的区别是你必须清理你拥有的动态分配的内存。(如果你动态分配它,你应该知道哪些内容)

动态内存的一个安全替代方法是使用std::shared_ptrstd::unique_ptr我不会在这里详细介绍,但它们可以为您节省内存管理的麻烦,所以请查阅它们。

  

我们如何决定my_list的类型。例如,如果我写的话   以下代码

     

ListNode l1(2); ListNode * my_list =&amp; l1;

这是指向堆栈上分配的内存的指针(所以不是动态的,因为你没有调用new)

  

列表中的最后5个对象是使用new创建的,如何删除   使用列表后,他们在main()?我是否必须遍历列表   并从列表末尾开始删除,直到创建所有对象   动态删除?

是的,如果你愿意的话,你可以循环遍历它们并以这种方式删除它们,但是你将如何进入上一个?另一种解决方案是:

ListNode* tempPtr;
while(my_list)  // This works since you are initializing next to null.
{
    tempPtr = my_list->next;
    delete my_list;
    my_list = tempPtr;
}
  

如果是这种情况,我认为这将是麻烦和不方便的。   如何在仍然返回的条件下改进createList()   指向ListNode对象的指针。

确实没有,如果你不在这里动态分配内存或使用静态或全局变量,它将在函数结束时消失。但是,您可以使用std::vectorstd::list执行与当前相同的操作。