简体   繁体   中英

delete a series of object created using new in another function from the main function

I came across a piece of code that use new to allocate dynamic memory in a function, then calls this function in the main function. I suspect there are some memory leak issue, but I do not know exactly how to fix it. The following code is simplified to demonstrate the problem:

#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;
}

If I understand it correctly, The function createList() creates a list which has 6 ListNode objects. Except the first object in the list (which is preHead ), the other 5 objects are all dynamically allocated using new . Finally, function createList() returns a pointer to the second object in the list, which is a pointer to dynamic memory.

My question is:

  1. Is my_list a normal pointer or pointer to dynamic memory? How do we decide the type of my_list .for example, if I write the following code

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

Then my_list will be a normal pointer to ListNode object. What is the difference between the 2 situations?

  1. The last 5 objects in the list are created using new , how to delete them in main() after using the list? Do I have to traverse the list and start deleting from the end of the list until all objects created dynamically are deleted?

  2. If that is the case, I think it will be cumbersome and inconvenient. How to improve createList() under the condition that it still returns a pointer to ListNode object.

Agreeing with the aforementioned suggestions of using std::list, I want to add the following: Q1) where do you see the distinction between a "normal pointer" and "pointer to dynamic memory"? A pointer to x is a pointer to x. You should know whether it is yours to delete. Q2) You either do what you suggested (deleting from the end) or

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

Is my_list a normal pointer or pointer to dynamic memory?

your pointer is a pointer, it is a variable that points to memory, there really is no difference between a pointer that points to memory that was dynamically allocated or memory that isn't. The only difference is you have to clean up dynamically allocated memory that you own.(Which you should know if you allocated it dynamically or not)

A safe alternative to dynamic memory is to use std::shared_ptr and std::unique_ptr I won't go into a lot of detail here but they can save you some trouble with memory management, so look them up.

How do we decide the type of my_list.for example, if I write the following code

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

This is a pointer to memory allocated on the stack (So not dynamic as you didnt call new)

The last 5 objects in the list are created using new, how to delete them in main() after using the list? Do I have to traverse the list and start deleting from the end of the list until all objects created dynamically are deleted?

Yes, you could loop through them all and delete them that way if you would like, but how are you going to get to the previous? Another solution is to do:

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

If that is the case, I think it will be cumbersome and inconvenient. How to improve createList() under the condition that it still returns a pointer to ListNode object.

There really isn't, if you don't dynamically allocate your memory here or use a static or global variable, it will be gone at the end of the function. You could however use a std::vector or an std::list to do the exact same thing you are currently doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM