Hello all,

Info: I am using Pelles C compiler.
Some code first:
Following is the linked list structure I am using.

typedef struct _NODESTRUCT
{
	void* data;
	struct _NODESTRUCT* next;
} NODESTRUCT, *PNODESTRUCT;

Method to add a new node to linked list:

PNODESTRUCT AppendNode(PNODESTRUCT rootNode, void *data)
{
	PNODESTRUCT tempNode;
	PNODESTRUCT currentNode;
	ginodestructsize = sizeof(NODESTRUCT);
	if(!rootNode)
	{
		rootNode = (PNODESTRUCT)malloc(ginodestructsize);
		currentNode = rootNode;
		currentNode->data = data;
	}
	else
	{
		currentNode =GetLastNode(rootNode);
		tempNode = (PNODESTRUCT)malloc(sizeof(NODESTRUCT));
		tempNode->data = data;
		currentNode->next = tempNode;
	}

	return currentNode;
}

Now a call to this method:

PNODESTRUCT rootnode;
PNODESTRUCT currentnode;
rootnode = NULL;
currentnode = AppendNode(rootnode, NULL);

Right after the first call I expect rootnode to have some value as I am trying to achieve from the method AppendNode. But even after AppendNode call, rootnode is NULL.

Any guesses why? Any help will be appreciated :)

Recommended Answers

All 5 Replies

>But even after AppendNode call, rootnode is NULL.
Yes, because any changes to rootnode within AppendNode will not persist back to main. In AppendNode, rootNode is a copy of the pointer, not a reference to it. I suspect you need more study on how pointers work between functions:

#include <stdio.h>

void foo(int *p, int **pp)
{
    printf("foo()\n\tp:   %p\n", (void*)&p);
    printf("\tpp:  %p\n", (void*)&pp);
    printf("\t*pp: %p\n", (void*)*pp);
}

int main()
{
    int i = 123;
    int *p = &i;
    int **pp = &p;

    printf("main()\n\tp:   %p\n", (void*)&p);
    printf("\tpp:  %p\n", (void*)&pp);
    printf("\t*pp: %p\n", (void*)*pp);
    foo(p, pp);

    return 0;
}

The way to pass a reference to an object in C is by passing a pointer to that object. Notice how the address of the pointer p in foo is different from the address of p in main. That's because foo's p is a copy of the pointer, a completely different object. If you change where p points to in foo, p in main doesn't change unless you pass a pointer to p (ie. pp), and modify the dereferenced object:

#include <stdio.h>

void wrong(int *p)
{
    p = NULL;
}

void right(int **p)
{
    *p = NULL;
}

int main()
{
    int i = 123;
    int *p = &i;
    
    printf("%snull\n", p == NULL ? "" : "NOT ");
    wrong(p);
    printf("%snull\n", p == NULL ? "" : "NOT ");
    right(&p);
    printf("%snull\n", p == NULL ? "" : "NOT ");

    return 0;
}

Thanks for the help, but I was doing it right:

I modified the code you had used, a bit, to test it:

#include <stdio.h>

void foo(int *p, int **pp)
{
    printf("main()\n\tp:   %p; %d\n", (void*)&p, (int)*p);
    printf("\tpp:  %p; %d\n", (void*)&pp, (int)**pp);
    printf("\t*pp: %p; %d\n", (void*)*pp, (int)**pp);
    *p = 100;
}

int main()
{
    int i = 123;
    int *p = &i;
    int **pp = &p;

    printf("main()\n\tp:   %p; %d\n", (void*)&p, (int)*p);
    printf("\tpp:  %p; %d\n", (void*)&pp, (int)**pp);
    printf("\t*pp: %p; %d\n", (void*)*pp, (int)**pp);
    foo(p, pp);
    printf("post foo() call\n\tp:   %p; %d\n", (void*)&p, (int)*p);
    printf("\tpp:  %p; %d\n", (void*)&pp, (int)**pp);
    printf("\t*pp: %p; %d\n", (void*)*pp, (int)**pp);

    return 0;
}

either way value of i and thus of *p and thus of **p is changing.
I did not think it was a coding error, looked more like compiler issue to me.
Thanks for the help :)
Output below:
[IMG]http://i53.tinypic.com/300fd53.jpg[/IMG]

>Thanks for the help, but I was doing it right
If you expected a reassignment of rootNode in AppendNode to change rootnode in main, you were doing it wrong.

>I did not think it was a coding error, looked more like compiler issue to me.
Only a fool blames the compiler first. Your code doesn't match your expectations. It's a misunderstanding of pointers, not a compiler issue.

>either way value of i and thus of *p and thus of **p is changing.
Yes! So you've got the basic concept down, now you need to apply it to pointers instead of integers. Instead of changing the value of i, change what p points to. I can guarantee that the only way you'll be able to manage it is by assigning to *pp. My second example illustrates what your code was doing with wrong(), and what your code should be doing with right().

commented: I am not really a fool, just caught with some oversight :D +4

*takes a deep breath*
Yes you were right... lol
I have to admit, I missed the most basic of pointer fundamentals >.<
and hey, am not a fool :P

>Yes you were right... lol
That's usually the case. ;)

>and hey, am not a fool
I didn't say you were. I said that only a fool blames the compiler first, though it could be expanded to "only a fool blames the compiler first...more than once". I think everyone needs to get burned by their ignorance one time before realizing that PEBKAC[1] is vastly more likely than a compiler bug.

As I often say in these situations, compilers are mature and heavily tested pieces of software, written and used by extremely computer literate people. The chances of a relative beginner finding a compiler bug in all but the most obscure and little used areas of the language are vanishingly small.


[1] PEBKAC - Problem Exists Between Keyboard And Chair

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.