Thread: linked list

  1. #1
    Registered User
    Join Date
    Jan 2002
    Posts
    41

    linked list

    // This code compiles fine but is there anything I should know also could you please put
    // me straight on my comment in the code Thanks all.

    [code]
    #include<iostream.h>
    #include<conio.h>
    #include<stdlib.h>

    #define MAX 30

    struct node create_node();
    void delete_nodes(struct node *start_ptr);
    void input_data(node *node);

    struct node{
    int age;
    char name[MAX];
    node *next;
    };

    int main()
    {
    node *top_ptr=NULL;

    *top_ptr=create_node();

    input_data(top_ptr);

    delete_nodes(top_ptr);

    return 0;
    }


    struct node create_node()
    {
    node *top=new node;

    if(top==NULL)
    abort();

    return *top; // Why do I need to return a pointer to a structure to another pointer
    } // as with *top rather than just top.

    void input_data(node *node)
    {
    cout<<"Input name->";
    cin>>node->name;

    cout<<'\n'<<"Input age->";
    cin>>node->age;
    }


    void delete_nodes(struct node *start_ptr)
    {
    node *hold;

    hold=start_ptr;

    if(hold!=NULL)
    cout<<'\n'<<"Memory freed",delete(hold);
    }
    [code:]

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    You have to keep track of every pointer value returned by "new" so that you can make a corresponding call to "delete" with that pointer value. Otherwise it's a memory leak.

    Don' t confuse the pointer value (what "new" returns) with the data that the pointer points to.

    Code:
        int *p;
    
        p = new int;
        *p = 5;
    
        cout << "p = " << (int)p << " (this must be given to delete)" << endl;
        cout << "*p = " << *p << " (this is the value at address 'p')" << endl;
    
        delete p;
    gg

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    That's not going to work. To begin with, you need to refer back to the text you're learning from and get a firmer grasp of the language. Anyway, here are the basic issues at hand:

    A pointer must point to something before being dereferenced.
    Dereferencing a pointer looks like this:

    >> return *top;

    Now look at this:

    >> *top_ptr=create_node();

    That would be correct syntax for dereferencing a pointer (although somewhat nonsensical in this case) if 'top_ptr' actually pointed to something.

    As for delete_nodes(), it might as well be named delete_node(), since it only deletes a single node.

    Finally, remember that it is IMPERITIVE that newly created node get their 'next' pointer to NULL, since that is how we will detect the end of the list.

    Here's the fix:

    Code:
    #include <iostream>
    #include <lib.h>
    
    #define MAX 30
    
    struct node * create_node();
    void delete_nodes(struct node *start_ptr);
    void input_data(node *node);
    
    struct node{
    int age;
    char name[MAX];
    node *next;
    };
    
    int main()
    {
     node *top_ptr=NULL;
    
     top_ptr=create_node();
    
     input_data(top_ptr);
    
     delete_nodes(top_ptr);
    
    return 0;
    }
    
    
    struct node * create_node()
    {
     node *top=new node;
    
     if(top==NULL)
      abort();
    
     top->next = NULL;
    
     return top; 
    } 
    
    void input_data(node *node)
    {
    cout<<"Input name->";
    cin>>node->name;
    
    cout<<'\n'<<"Input age->";
    cin>>node->age;
    }
    
    
    void delete_nodes(struct node *start_ptr)
    {
     node *hold;
    
        while(start_ptr != NULL)
       {
        hold = start_ptr;
        start_ptr = start_ptr->next;
        cout << "Memory freed for '" << hold->name << "'" << endl;
        delete(hold);
       }
    
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    With C++ you only need to use the keyword struct with the declaration of the struct interface, not with each use of struct as a parameter or as an object. Therefore, drop struct in each of the following two lines:

    struct node create_node();
    void delete_nodes(struct node *start_ptr);

    and other extraneous places other than

    Code:
    struct node
    {};
    Secondly, compiling is different than running. Does the code provide the output you want. I suspect it's a bit difficult to say as you never attempt to use the list except to fill it and the delete it. If you do that I think you'll find an error that I made yesterday. That is, in order to change the value of a pointer in the calling function in a called function you need to pass the pointer by reference, not by value. To demonstrate this to yourself add the following line after the call to input_data() in main

    cout << "top_ptr->age = " << top_ptr->age << " and top_ptr>name is " << top_ptr->name << endl;

    and at the end of input_data() before the return statement put this line:

    cout << "node->age = " << node->age << " and node->name is " << node->name << endl;

    To fix this change this:

    void input_data(node *node);

    to this;

    void input_data(node ** node);

    and then handle the levels of indirection as necessary in input_data(). Post if you can't figure that out.

    Third, to answer your question, create_node() returns a node, not a pointer to a node. Therefore you need a node to assign it to in main(). Since top_ptr is a pointer to a node, you need to derefence the pointer back to the node it points to by using the derefernce operator as you did, or have the return from create_node() be a pointer to a node, not a node, in which case you don't need to dereference top_ptr or top.

    Fourth, note that your current code only creates and destroys a single node each run through the program. You will want to expand it to allow the user to add and delete more than one node per program at some point. That will will require use of loops.

    I see that some of my points have already been reported from a slightly different perspective, so excuse the redunancy where it exists.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Elad, the only reason you would need to pass the address of the pointer is if were 'repointing' it somewhere else. ie:

    Code:
    void repoint(node ** ptr, node * new_address)
    {
     *ptr = new_address;
    }
    So the prototype here remains:

    >> void input_data(node *node);
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Shoulda known I'd blow it again. So let's see if I get this straight, finally. (Well, at least 'til I try to work with C style lists or other intense uses of pointers).

    if instead of this:
    Code:
    node * create_node()
    {
      node * top=new node;
      
      if(top==NULL)
        abort();
    
       top->next = NULL;
    
       return top; 
    }
    it had been this:
    Code:
    void create_node(node * top_ptr)
    {
       top_ptr = new node;
       
       if(top==NULL)
        abort();
    
       top_ptr->next = NULL;
    }
    it would be an error since top_ptr is being re-directed. In this scenario you need to send top_ptr by reference as in this example:
    Code:
    void create_node(node ** topPtr)
    {
       *topPtr = new node;
    
       if(*topPtr == NULL)
        abort();
    
       (*topPtr)->next = NULL;
    }
    Returning a node pointer rather than using a node pointer as a parameter when trying to change the address in the pointer makes the syntax a little cleaner.

    However, here:
    Code:
    void input_data(node *node)
    {
    cout<<"Input name->";
    cin>>node->name;
    
    cout<<'\n'<<"Input age->";
    cin>>node->age;
    }
    the node pointer is used to change the value at the address it is pointing to, not change the address the node is pointing to. Therefore, the pointer doesn't need to be passed by reference, it _is_ the "reference" used to change the value.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Linked list program need help !!!
    By dcoll025 in forum C++ Programming
    Replies: 1
    Last Post: 04-20-2009, 10:03 AM
  2. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  3. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  4. Template Class for Linked List
    By pecymanski in forum C++ Programming
    Replies: 2
    Last Post: 12-04-2001, 09:07 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM