Thread: new and my Linked_list class

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    178

    new and my Linked_list class

    I have a question regarding the use of new within my class definition: when I call delete in main, does it free all memory allocated for each node and for list or just list?

    Code:
    //linked_list.h
     
    #ifndef LINKED_LIST_H
    
    #define LINKED_LIST_H
    
    #include <iostream>
    #include <string>
    
    class Linked_list {
    public:
    	Linked_list();
    	Linked_list *startnode(std::string data, Linked_list *node);
    	Linked_list *addnode(std::string data, Linked_list *node);
    	Linked_list *delnode(Linked_list *node);
    	void display(Linked_list *a_list) const;
    private:
    	Linked_list *link;
    	std::string data;
    };
    
    #endif
    Code:
    // Linked_list.cpp
     
    #include "Linked_list.h"
    
    using namespace std;
    
    Linked_list::Linked_list() : link(0), data(" ") {}
    
    Linked_list *Linked_list::startnode(std::string data, Linked_list *node)
    { 
    	node->data = data; 
    	node->link = 0; 
    	return node;
    }
    
    Linked_list *Linked_list::addnode(std::string data, Linked_list *node)
    { 
    	Linked_list *next = new Linked_list; 
    	next->data = data; 
    	next->link = node; 
    	return next; 
    }
    
    Linked_list *Linked_list::delnode(Linked_list *node)
    {
    	Linked_list *head = node;
    	head = head->link;
    	node->link = 0;
    	return head;
    }
    
    void Linked_list::display(Linked_list *a_list) const
    {
    	while(a_list != 0)
    	{
    		cout << a_list->data << endl;
    		a_list = a_list->link;
    	}
    }
    Code:
    #include "Linked_list.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {	
    	Linked_list *a_list = new Linked_list;
    	string word = "Jesus";
    	
    	a_list = a_list->startnode(word, a_list);
    	
    	word = "Glory to God!";
    	
    	a_list = a_list->addnode(word, a_list);
    		
    	a_list->display(a_list);
    	
    	delete a_list;
    	
    	return 0;
    }
    Thank you in advance for your kind support of my question.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Is there a reason you are using new in main instead of just creating an instance of your list?
    Code:
    Linked_list a_list;

    Jim

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    266
    Imanuel, you're right in thinking that it does not free the memory from each of your nodes.

    If you want to make sure this happens on 'delete' or when your list goes out of scope, look into something called a 'Destructor': Destructor (computer programming) - Wikipedia, the free encyclopedia

    This will involve implementing a method called '~Linked_list'.
    Check out my programming / algorithm blog @ http://www.swageroo.com

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by jimblumberg View Post
    Is there a reason you are using new in main instead of just creating an instance of your list?
    Code:
    Linked_list a_list;
    Jim
    Actually Linked_list *a_list; I used new in main() because I was receiving EXEC_BAD_ACCESS errors indicating I did not have any memory set aside for my pointer to type Linked_list.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by rodrigorules View Post
    Imanuel, you're right in thinking that it does not free the memory from each of your nodes.

    If you want to make sure this happens on 'delete' or when your list goes out of scope, look into something called a 'Destructor': Destructor (computer programming) - Wikipedia, the free encyclopedia

    This will involve implementing a method called '~Linked_list'.
    Thank you rod. I have yet to arrive at that point within my text but anticipate it.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by Imanuel View Post
    I have a question regarding the use of new within my class definition: when I call delete in main, does it free all memory allocated for each node and for list or just list?

    Code:
    //linked_list.h
     
    #ifndef LINKED_LIST_H
    
    #define LINKED_LIST_H
    
    #include <iostream>
    #include <string>
    
    class Linked_list {
    public:
    	Linked_list();
    	Linked_list *startnode(std::string data, Linked_list *node);
    	Linked_list *addnode(std::string data, Linked_list *node);
    	Linked_list *delnode(Linked_list *node);
    	void display(Linked_list *a_list) const;
    private:
    	Linked_list *link;
    	std::string data;
    };
    
    #endif
    Code:
    // Linked_list.cpp
     
    #include "Linked_list.h"
    
    using namespace std;
    
    Linked_list::Linked_list() : link(0), data(" ") {}
    
    Linked_list *Linked_list::startnode(std::string data, Linked_list *node)
    { 
    	node->data = data; 
    	node->link = 0; 
    	return node;
    }
    
    Linked_list *Linked_list::addnode(std::string data, Linked_list *node)
    { 
    	Linked_list *next = new Linked_list; 
    	next->data = data; 
    	next->link = node; 
    	return next; 
    }
    
    Linked_list *Linked_list::delnode(Linked_list *node)
    {
    	Linked_list *head = node;
    	head = head->link;
    	node->link = 0;
    	return head;
    }
    
    void Linked_list::display(Linked_list *a_list) const
    {
    	while(a_list != 0)
    	{
    		cout << a_list->data << endl;
    		a_list = a_list->link;
    	}
    }
    Code:
    #include "Linked_list.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {	
    	Linked_list *a_list = new Linked_list;
    	string word = "Jesus";
    	
    	a_list = a_list->startnode(word, a_list);
    	
    	word = "Glory to God!";
    	
    	a_list = a_list->addnode(word, a_list);
    		
    	a_list->display(a_list);
    	
    	delete a_list;
    	
    	return 0;
    }
    Thank you in advance for your kind support of my question.
    If I defined a destructor as such:

    Code:
    Linked_list::~Linked_List() {delete link;}
    within the class definition, would I no longer need to call delete on a_list in main because once a_list went out of scope, the destructor is called? I am not certain if I have ensure no dangling pointers as well as no memory leaks. I am using Xcode and with an infinite loop running after the following two explicit calls to their destructors:

    Code:
    a_list->Linked_list::~Linked_list();
    b_list->Linked_list::~Linked_list();
    I profiled the run using Leaks widget and discovered no leaks but I could be misinterpreting the results and uncertain about the use of the destructor.

    Thank you in advance for your assistance.
    Last edited by Imanuel; 09-13-2012 at 08:37 AM.

  7. #7
    Registered User
    Join Date
    Nov 2005
    Posts
    673
    You dont call a destructor. It is called automatically when a object goes out of scope or when a 'new'd object is 'delete'd.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by Raigne View Post
    You dont call a destructor. It is called automatically when a object goes out of scope or when a 'new'd object is 'delete'd.
    True, I understand that but I am calling new in my member function definitions and new in main. When I defined a destructor on Linked_list *link, do I simply let the code go out of scope without calling delete in main? I want to be certain I am not leaking memory when I am ready to completely free my Linked_list.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I suppose I should let you in on the rule of three now: generally, if you define the copy constructor, copy assignment operator or destructor, you should define all three.

    The reason is that, unless you are just declaring the destructor to be virtual, the need to define one of them likely means that objects of your class is doing some kind of manual memory (resource) management, hence you have to ask what happens to the resource not only when the object is destroyed, but also when the object is copied. Sometimes, this means that you don't want the object to be copied, in which case you would disable copying by declaring (but not defining) the copy constructor and copy assignment operator as private.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by laserlight View Post
    I suppose I should let you in on the rule of three now: generally, if you define the copy constructor, copy assignment operator or destructor, you should define all three.

    The reason is that, unless you are just declaring the destructor to be virtual, the need to define one of them likely means that objects of your class is doing some kind of manual memory (resource) management, hence you have to ask what happens to the resource not only when the object is destroyed, but also when the object is copied. Sometimes, this means that you don't want the object to be copied, in which case you would disable copying by declaring (but not defining) the copy constructor and copy assignment operator as private.
    I defined both a copy constructor and assignment operator= including a destructor. My question is how I know for this program that instances of new in member functions and in main results in all used memory returning to the free store or am I dealing with leaks?

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Imanuel
    I defined both a copy constructor and assignment operator= including a destructor. My question is how I know for this program that instances of new in member functions and in main results in all used memory returning to the free store or am I dealing with leaks?
    By careful examination of your code; by using a memory leak checker, etc. Actually, one of the best ways is to ditch your class and use std::list, but I suspect that that would defeat the purpose of this exercise

    Anyway, one of the problems I see is that you are not actually making use of class membership. Consider:
    Code:
    void Linked_list::display(Linked_list *a_list) const
    {
        while(a_list != 0)
        {
            cout << a_list->data << endl;
            a_list = a_list->link;
        }
    }
    Why on earth do you pass a pointer to a Linked_list to this member function? I would expect something like:
    Code:
    void Linked_list::display() const
    {
        Linked_list *node = link;
        while (node != 0)
        {
            cout << node->data << endl;
            node = node->link;
        }
    }
    (You may need to fix this for const-correctness.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by laserlight View Post
    By careful examination of your code; by using a memory leak checker, etc. Actually, one of the best ways is to ditch your class and use std::list, but I suspect that that would defeat the purpose of this exercise

    Anyway, one of the problems I see is that you are not actually making use of class membership. Consider:
    Code:
    void Linked_list::display(Linked_list *a_list) const
    {
        while(a_list != 0)
        {
            cout << a_list->data << endl;
            a_list = a_list->link;
        }
    }
    Why on earth do you pass a pointer to a Linked_list to this member function? I would expect something like:
    Code:
    void Linked_list::display() const
    {
        Linked_list *node = link;
        while (node != 0)
        {
            cout << node->data << endl;
            node = node->link;
        }
    }
    (You may need to fix this for const-correctness.)
    Why do you bother to post when you are of no assistance? Your contributions have been the least helpful. I am not asking for a critique of the code but assistance in better understanding and using destructors to ensure I can avoid memory leaks.

    Try to respond on topic than with your non-whit, dry humor foolishness. Thank you and have a kind day.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Imanuel
    Why do you bother to post when you are of no assistance? Your contributions have been the least helpful.
    I note that no one mentioned the rule of three before I did. Since my contributions "have been the least helpful", I shall stop helping you after this post. Go ahead and shoot yourself in the foot with C++.

    My suggestion to use std::list, while made in jest, really is a way to avoid memory leaks. Refer to Stroustrup's answer to the FAQ How do I deal with memory leaks?

    Quote Originally Posted by Imanuel
    I am not asking for a critique of the code but assistance in better understanding and using destructors to ensure I can avoid memory leaks.
    I am giving a critique of your code because you posted code. Pretending that flaws in your code are not relevant won't help you. In fact, making use of class membership is a way to avoid memory leaks: with the unnecessary pointer argument, you are making your code unnecessarily complicated and hence harder to reason about.

    Essentially, I see an overall problem with your class design. Take a look at the interface of std::list for an example of one way to approach this that makes use of the Resource Acquisition Is Allocation (RAII) idiom to avoid memory leaks.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    178
    Quote Originally Posted by laserlight View Post
    I note that no one mentioned the rule of three before I did. Since my contributions "have been the least helpful", I shall stop helping you after this post. Go ahead and shoot yourself in the foot with C++.

    My suggestion to use std::list, while made in jest, really is a way to avoid memory leaks. Refer to Stroustrup's answer to the FAQ How do I deal with memory leaks?


    I am giving a critique of your code because you posted code. Pretending that flaws in your code are not relevant won't help you. In fact, making use of class membership is a way to avoid memory leaks: with the unnecessary pointer argument, you are making your code unnecessarily complicated and hence harder to reason about.

    Essentially, I see an overall problem with your class design. Take a look at the interface of std::list for an example of one way to approach this that makes use of the Resource Acquisition Is Allocation (RAII) idiom to avoid memory leaks.
    I apologize laserlight. I was frustrated, so please forgive me. I rewrote the class and discarded pointer returns, pointer variables, and use of pointers everywhere except to point to another Linked_list. Now I need to implement a smart pointer helper class.

    Thank you for your help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-17-2008, 02:31 AM
  2. Replies: 7
    Last Post: 05-26-2005, 10:48 AM
  3. Replies: 2
    Last Post: 04-06-2005, 07:25 AM
  4. Template <class T1, class T2, class T3> error LNK2019
    By JonAntoine in forum C++ Programming
    Replies: 9
    Last Post: 10-11-2004, 12:25 PM
  5. Replies: 1
    Last Post: 12-11-2002, 10:31 PM