New Pointer has the same address as an existing pointer

I have the following situation. The weird thing is, is that this issue only pops up after a few nodes have been appended to the list. There is a description of my issue. If you need any additional information please let me know.

Thank you for your time,
Brandon

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
void List::Append(string newword)
{
	// Temporary node
	Node* pTemp = NULL;
	pTemp = head;

	// Create a new node
	Node* pTail = NULL;
	pTail = new Node;

	//If we look at the address of pTail here, it is the same as head?????!!!!???
	// Watches:
	// head = (Node*) 0x804f1e8
	// newword = "slowly"
	// num = 3
	// pTemp = (Node*) 0x804f1e8
	// pTemp->next = (Node*) 0x804f1e8,,
	// pTail = (Node*) 0x804f1e8
	// These values make no sense, pTail is a NEW node, why? and how can i fix this?

	pTail->next = NULL;
	pTail->word = newword;

	// Make sure there are nodes in the list
	if(head == NULL)
	{
		head = pTail;
	}
	else
	{
		// Find the last node in the list
		while(pTemp->next != NULL)
		{
			pTemp = pTemp->next;
		}
		pTemp->next = pTail;
	}

	// Increment the node count
	num = num + 1;
}
I have decided to rewrite the function a bit more robustly, and I think you would be interested in knowing that the problem still occurs in the same spot (when num==3 and newword=="slowly"). I have included the new code:

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
void List::Append(string newword)
{
    Node* pNewTail = NULL;
    Node* pOldTail = head;

    // Create the new Tail Node
    pNewTail = new Node;
    pNewTail->next = NULL;
    pNewTail->word = newword;

    // Find the current tail node
    for(int i=0; i<num-1; i++)
    {
        pOldTail = pOldTail->next;
    }

    // Add the new tail to the end
    if(head != NULL)
    {
        pOldTail->next = pNewTail;
    }
    else
    {
        head = pNewTail;
    }

    // Increment num
    num = num + 1;
}
unless the head is being deleted somewhere, you're right, that makes no sense at all. In fact it makes so little sense that I'm not even sure I believe it's happening. I think you must be misdiagnosing the problem and/or misinterpreting the debugger.

How large is the whole class? Can you post it? Maybe if I can recreate the problem I can diagnose it more easily.



On an unrelated note... why do you initialize things to null when you're just assigning them right afterwards?

1
2
3
4
5
6
7
// why do this?
Node* pTemp = NULL;
pTemp = head;


// why not just do this?
Node* pTemp = head;



Another curiosity...

1
2
3
4
5
6
// why this
num = num + 1;


// instead of this:
num += 1;
This was just an attempt at fiddling with things to try to get them to work.
1
2
3
4
5
6
7
// why do this?
Node* pTemp = NULL;
pTemp = head;


// why not just do this?
Node* pTemp = head;



And this is just personal taste I suppose. I don't like abbreviations.
1
2
3
4
5
6
// why this
num = num + 1;


// instead of this:
num += 1;


Sure thing, This is actually a project for school but I have uploaded the entire source to dropbox. You will need to run the program with the command line argument "p04input3.txt". That is the file that I ran into the problem with.

http://dl.dropbox.com/u/8241732/Project4.zip

Thank you for your time,
Brandon
A wild guess, but one possibility may be that head has never been initialized.

Under this hypothesis, in subsequent runs, head may just happen to point to the same location from a previous run - hard to tell without seeing the whole program.

But the first place I would check is the List constructor to make sure that you have initialized head to be NULL.
And this is just personal taste I suppose. I don't like abbreviations.


FWIW, you should break that habit.

For overloaded operators, it's very possible for x += y; to have better performance than x = x + y;

Not to mention it's less typing.

But I guess it doesn't really matter.


Anyway I'll check this out.
I have attached the full source in a previous post but head IS initialized to NULL upon construction of the list object.
But the first place I would check is the List constructor to make sure that you have initialized head to be NULL.


1
2
3
4
List::List()
    : head(NULL),
      num (0)
{}


Full Source:
http://dl.dropbox.com/u/8241732/Project4.zip
OK - I am on a public computer atm, so no way to download, compile and run. I will take a look at home in a few hours, if you have not solved it already.

You probably have some memory corruption issue (may want to try valgrind if you run out of ideas to test or have trouble stepping through your code to narrow down the problem - at some point before the Append() call, your head may have been corrupted - narrow down where it may be happening).
OK - I got home and cranked your code through valgrind. Essentially, valgrind thinks you have corruption at list.cpp:180 where you delete pTemp. As usual, it wasn't perfect, but it was great for narrowing down the vicinity of the problem; it also caught the problem earlier than we would expect: during the first run. I looked at your implementation carefully and the delete looks right on Line 180. However, the point of corruption gave me a clue. It was during the first run, when you were trying to delete "See" at the head of your list.

I eyeballed your code some more and replace list.cpp:154
pTemp = head;
with
head = pTemp->next; // since we are going to delete the head node, make sure we repoint head

Reran valgrind to verify and it all worked. So it was memory corruption after all. I would recommend that you download and install valgrind - with this tool, I was able to debug this code in about 10 minutes:

http://valgrind.org/

This kind of spookiness is typical of memory corruption. When strange program behavior starts to make you believe in voodoo, it's a good idea to pull out some memory-checking tools to get your sanity back.

GL.

BTW, +1 Disch:
unless the head is being deleted somewhere, you're right, that makes no sense at all.
Damn! He's good! Listen to all his recommendations.

For your benefit, this is a snippet of what a valgrind run with output looks like:

/tmp/Project4/$ valgrind ./p04 p04input3.txt
==11379== Memcheck, a memory error detector
==11379== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==11379== Using Valgrind-3.6.0.SVN and LibVEX; rerun with -h for copyright info
==11379== Command: ./p04 p04input3.txt
==11379== 

## p04input3.txt -- Test List(), ~List(), Delete()

# Test successful delete

List() -- Successful
Print() -- Head { }
Append(See) -- successful
Print() -- Head { See }
Append(Spot) -- successful
Print() -- Head { See Spot }
Append(run) -- successful
Print() -- Head { See Spot run }
Append(swiftly) -- successful
Print() -- Head { See Spot run swiftly }
Append(away) -- successful
Print() -- Head { See Spot run swiftly away }
Delete(run) -- successful
Print() -- Head { See Spot swiftly away }
Delete(Spot) -- successful
Print() -- Head { See swiftly away }
Delete(See) -- successful
==11379== Invalid read of size 8
==11379==    at 0x4ECAB20: std::basic_ostream<char, std::char_traits<char> >& std::operator<< 
<char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, 
std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > 
const&) (in /usr/lib/libstdc++.so.6.0.13)
==11379==    by 0x4028A6: List::Print() const (list.h:89)
==11379==    by 0x402347: main (main.cpp:116)
==11379==  Address 0x5962440 is 0 bytes inside a block of size 16 free'd
==11379==    at 0x4C27EFF: operator delete(void*) (vg_replace_malloc.c:387)
==11379==    by 0x401A65: List::Delete(std::string) (list.cpp:180)
==11379==    by 0x402142: main (main.cpp:90)
Last edited on
I eyeballed your code some more and replace list.cpp:154
pTemp = head;
with
head = pTemp->next; // since we are going to delete the head node, make sure we repoint head

Brilliant! That fixed it for me. I appreciate it very much!

BTW, +1 Disch:

will do!

Reran valgrind to verify and it all worked. So it was memory corruption after all. I would recommend that you download and install valgrind - with this tool, I was able to debug this code in about 10 minutes

I just installed it via the Ubuntu Repositories. I'll give it a go next time I run into an issue.


Thanks guys!
Brandon
Glad you're giving valgrind a try... ...if all posters listed their problems with great test code like the way you did, they would all get their answers much more quickly!

Good luck with your class/programming.
if all posters listed their problems with great test code like the way you did, they would all get their answers much more quickly!


+1

It's so much easier to help when the question/problem is stated clearly and is reproducible. Too many posters simply don't know how to ask a question. =(
Its nice to have a nice community like here on cplusplus.com, Its a welcome change from the "rudeness" of the sun java forums.

Thanks again!
Brandon
Topic archived. No new replies allowed.