Question

It seems that I can't figure out why the while loop wont terminate.

It should be while(null) essentially.

I can't figure it out.

All help would be appreciated :D

I dont know what could possibly be stopping the while loop at all? It says that the first entry gets stored, and the entry for next is at 0x0000000000 and ??? name and ??? ??? coords so it is in fact NULL. I tried adding in the constructor next = 0; instead of next = NULL and it still did not work.

Thanks guys.

Anthony

EDIT:  Value of nodePtr = 00000000 if next = 0 in the constructor
       Value of nodePtr = 00899FE0 if next = NULL in the constructor
if adding a cout << nodePtr->next; before the while.

http://pastebin.com/7usYdfHB -- Full program for reference.

EDIT2: http://i.imgur.com/fKCoSjV.png Is the popup when I go to enter the 2nd entry.

void LinkedList::appendNode(string name, double x, double y)
{
        ListNode* newNode; // To point to new node
        ListNode* nodePtr; // To traverse List

        // allocate new node
        newNode = new ListNode(name, x, y);

        // If no head, head is the newNode
        // else traverse the list to find the end and append newNode
        if (!head)
        {
                head = newNode;
                cout << "Record inserted successfully.\n" << endl;
        }
        else
        {
                nodePtr = head;

                //traverse the list loop
                while (nodePtr->next) //VS 2012 locks up here <-----
                {

                        //Checks for duplicate entry by name
                        if (nodePtr->cityName == name)
                        {
                                cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
                                return;
                        }
                        //traverse the list
                        nodePtr = nodePtr->next;
                }
                // checks 2nd entry, as while loop wont run for a 2nd entry.
                if (nodePtr->cityName == name)                  {
                        {
                                cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
                                return;
                        }
                }
                // if next is NULL add newNode
                else if (!nodePtr->next)
                {
                        nodePtr->next = newNode;
                        cout << "Record inserted successfully.\n" << endl;
                }
        }
Was it helpful?

Solution

Aside from the obvious memory leak when an attempt to insert an already existing name is made, your code seems to work fine. It works fine when either 0 or NULL is used to initialize the pointers. It makes no difference.

(One wild guess I can make is that in your actual calling code (which you do not show), you somehow managed to pass your LinkedList around by value. Since your LinkedList does not satisfy the Rule of Three, the integrity of the list got violated, which lead to undefined consequences you observed.)

BTW, by using an extra level of indirection you can simplify your heavily branched appendNode function into a significantly more compact and almost branchless one

void LinkedList::appendNode(string name, double x, double y)
{
        ListNode** pnodePtr;

        for (pnodePtr = &head; *pnodePtr != NULL; pnodePtr = &(*pnodePtr)->next)
                if ((*pnodePtr)->cityName == name)
                        break;

        if (*pnodePtr == NULL)
        {
                  *pnodePtr = new ListNode(name, x, y);
                  cout << "Record inserted successfully.\n" << endl;
        }
        else
                  cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
}

(I also eliminated the leak.) Specifically, this technique allows one to avoid writing a dedicated branch for processing the head node.

Also (referring to the full version of the code), in your functions from "delete by coordinate" group you for some reason check both x and y coordinates of the head node, but only one coordinate of the other nodes down the list. Why? This is rather weird and does not seem to make much sense. Meanwhile, functions from "search by coordinate" group do not have this issue - they process all nodes consistently.

Also, your displayList function suffers from a stray return at the very beginning, which is why it never prints anything. You need to add a pair of {} to properly group your statements.

OTHER TIPS

I tried to reproduce your problem but could not. I reverse engineered your ListNode and LinkedList classes. The code below works, maybe that will help you sort out your issue. I refactored it a little to simplify it (going further you should consider keeping track of the end of the list as this will help with other operations that your list will need). Be sure to implement a destructor for your LinkedList class to clean up the nodes.

#include <string>
#include <iostream>

using namespace std;

struct ListNode
{
    string cityName;
    double m_x, m_y;
    ListNode* next;

    ListNode(string name, double x, double y) : cityName(name), m_x(x), m_y(y), next(nullptr)
    {}
};

class LinkedList
{
    ListNode* head;
public:
    LinkedList() : head(nullptr)
    {
    }
    ~LinkedList()
    {
    }
    void LinkedList::appendNode(string name, double x, double y)
    {
        ListNode* newNode; // To point to new node

        // allocate new node
        newNode = new ListNode(name, x, y);

        // If no head, head is the newNode
        // else traverse the list to find the end and append newNode
        if (!head)
        {
            head = newNode;
            cout << "Record inserted successfully.\n" << endl;
        }
        else
        {
            ListNode *nodePtr = head;
            ListNode *prevNode = nullptr;

            //traverse the list loop
            while (nodePtr)
            {

                //Checks for duplicate entry by name
                if (nodePtr->cityName == name)
                {
                    cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
                    return;
                }
                //traverse the list
                prevNode = nodePtr;
                nodePtr = nodePtr->next;
            }
            // if next is NULL add newNode
            if (prevNode)
            {
                prevNode->next = newNode;
                cout << "Record inserted successfully.\n" << endl;
            }
        }
    }
};

int main()
{
    LinkedList list;

    list.appendNode("New York", 1.0, 2.0);
    list.appendNode("Boston", 1.5, 2.5);
    list.appendNode("Miami", 1.7, 2.7);
    list.appendNode("Miami", 1.7, 2.7);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top