Stop Pointing

I am writing a helper function that is to be used by both a copy constructor and an overloaded assignment operator. The function is to copy a linked list that has several pointers: headPtr, precursor, cursor, and tailPtr. I think I got the function working okay, but the problem is when I get to the end of the list there is an additional garbage value which is printed out. When I look through the debugger, it looks like cursor is pointing to a next node which is the garbage value printed. I have tried setting cursor->next to nullptr when reaching the end of the list, as well as a lot of wrestling with the code but its not working. How do I get the end of the list to stop pointing correctly?

Below is what the debugger gives for cursor, and -842150451 is the extra garbage value that is printed. The rest of the list before that is okay.

+ cursor 0x00970e88 {data=60 next=0x00970f68 {data=-842150451 next=0xcdcdcdcd {data=??? next=??? } } } cs_sequence::Sequence::Node *

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void Sequence::copy(const Sequence& copyMe) 
    {        
            if (copyMe.headPtr == this->tailPtr) 
            {
                delete headPtr;
                headPtr = tailPtr = cursor = precursor = nullptr;
            }

            else
            {
                Node* traverseList = copyMe.headPtr;           // Make a counter that is to traverse the list to be copied.  
                this->headPtr = new Node;                        // Make first node.
                Node* copyList = this->headPtr;

                while (traverseList != nullptr)
                {
                    copyList->data = traverseList->data;       // Copy data.
                    copyList->next = new Node;                  

                    tailPtr = copyList;
                    if (copyList->data == copyMe.cursor->data)
                    {
                        cursor = copyList;
                        //cursor->next = nullptr;
                    }
                    if (copyList->data == copyMe.precursor->data)
                    {
                        precursor = copyList;
                    }

                    traverseList = traverseList->next;         // Advance to next node in original list.
                    copyList = copyList->next;
                                       
                    numItems++;
                    cout << "Test tailPtr" << tailPtr->data << endl;

                }
                
               
            }
     }
The reason is line 18. The member next of copyList is set to new but probably uninitialized Node while cursor/precursor is set to copyList. I don't know what it is good for but if you want nullptr for next in cursor/precursor you need to change line 18 to:

copyList->next = nullptr; // new Node;
Cursor and precursor show the correct values in the debugger. cursor =60, precursor = 59.

The list print 1 2 3 4 5 . . . 60 -842150451. I just need to get rid of the -842150451.

My thought in having nullptr for next is on line 24. I tried that with delete cursor->next; right before it as well but that didn't work either.
Post Node::Node(). I agree with coder777 that the constructor is likely leaving the members uninitialized.
Last edited on
> next=0xcdcdcdcd
https://stackoverflow.com/questions/370195/when-and-why-will-a-compiler-initialise-memory-to-0xcd-0xdd-etc-on-malloc-fre#370362
In debug builds, memory is filled with 0xCD just before it's given to you.

Likewise, your -842150451 is 0xcdcdcdcd as a signed decimal.

You didn't initialise something.
I looked at the link and can see that the compiler gives 0xCD for addresses generated with new. Seems to be for the purpose of creating patterns that make debugging easier.

What I am understanding is that -842150451 is just some garbage value because it has not been initialized. It is not supposed to be initialized though. For the list 1 - 60, when it hits 60 it's supposed to stop, but prints the additional garbage value -842150451.
I'll post the default constructor too.

1
2
3
4
5
6

Sequence::Sequence() : numItems(0), headPtr(nullptr), tailPtr(nullptr),
                           cursor(nullptr), precursor(nullptr)
    {
    }
Update, I changed my first if statement to:

1
2
3
4
5
6
7
8

if (copyList->data == copyMe.cursor->data) // If cursor is at tail
                    {
                        cursor = copyList;
                        delete cursor->next;
                        cursor->next = nullptr;
                    }


This will get rid of the -842150451, and make the list stop at 60 like it should. However, my approach only works for the test with cursor at a tail.

The next test is cursor near the middle. It looks like with the above code, the next node is deleted so I can't copy the list past the cursor.

Anyone have ideas on how to strategize the code to to past test for:
Cursor at tail.
Cursor near middle.
Cursor at head.
No cursor.
Sequence::Sequence() appears to be initializing everything to nullptr or zero, except next, which is left uninitialized. If you fix that I'm confident the bug will go away.
I added next(nullptr) to the list in the default constructor, but I get a red squiggly line under "next" that says "next is a nonstatic member or base class..."

The Node data and next members are organized in a struct in the private section of the Sequence class. I tried using the scope resolution operator, Node::next(nullptr) , to get the compiler to recognize next but that didn't work. Also tried Sequence::Node::next(nullptr) with no luck.
I added next(nullptr) to the list in the default constructor, but I get a red squiggly line under "next" that says "next is a nonstatic member or base class..."
Post how your constructor looks with next added to the initialization list.
Taking a closer look shows that the whole copy process is flawed. Consider this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void Sequence::copy(const Sequence& copyMe) 
    {        
            if (this != &copyMe) // Avoid copying to itself.
            {
                // Note: The target Sequence must always be destroyed before copying
                delete headPtr; // memory leak? What about the other nodes?
                headPtr = tailPtr = cursor = precursor = nullptr;

                Node* traverseList = copyMe.headPtr;           // Make a counter that is to traverse the list to be copied.  
                Node* copyList = nullptr;

                while (traverseList != nullptr)
                {
if(this->headPtr)
{
                   copyList->next = new Node;                  
                   copyList = copyList->next;
}
else
{
                this->headPtr = new Node;                        // Make first node.
                copyList = this->headPtr;
}
                    copyList->next = nullptr; // Note: The constructor of Node is supposed to do this
                    copyList->data = traverseList->data;       // Copy data. Better pass to constructor...

                    tailPtr = copyList;
                    if (copyList->data == copyMe.cursor->data)
                    {
                        cursor = copyList;
                        //cursor->next = nullptr;
                    }
                    if (copyList->data == copyMe.precursor->data)
                    {
                        precursor = copyList;
                    }

                    traverseList = traverseList->next;         // Advance to next node in original list.
                                       
                    numItems++;
                    cout << "Test tailPtr" << tailPtr->data << endl;

                }
                
            }
     }
Not tested!
I got the function working. Thank you for the example, and everyone's help.
Topic archived. No new replies allowed.