4

I was writing some C-code to implement basic Stack data structure operations like push,pop,etc. I'm using the Linked List implementation of the stack. In this implementation, every time I push a value into the stuck, I create a new node, and set it as the head node of my Linked List. So this involves changing the references of the head node.

void push(stack **t, int ele)
{
stack *new, *temp;
temp=*t;
new=(stack *)malloc(sizeof(stack));
if(new==NULL)
{
    printf("\n stack overflow");
    return;
}
new=(stack *)malloc(sizeof(stack));
new->val=ele;
new->next=*t;
*t=new;

}

If I were to write a similar code using single pointers, then it would be like this

void push(stack *t, int ele)
{
stack *new, *temp;
temp=t;
new=(stack *)malloc(sizeof(stack));
if(new==NULL)
{
    printf("\n stack overflow");
    return;
}
new=(stack *)malloc(sizeof(stack));
new->val=ele;
new->next=t;
t=new;

}

In the function, the head node(**t) appears on the RHS of assignment in all steps but this

 *t=new;

Basically the first code assigns 'new' to the pointer of **t, that is *t, and the second code assigns 'new' to the pointer of *t, that is t. Both seem to be requiring only the single pointer to the head node to be assigned as 'new', yet only the first code works, and second doesn't actually modify the head node value.

What is the explanation for this to happen? Why doesn't the second code work in a similar way to the first?

6
  • 1
    You need to modify the pointer to the first stack element that is passed to push(), hence you need a parameter of pointer to pointer type. In the second function, assignment to t is not visible outside the function. Commented Mar 27, 2013 at 18:52
  • Is it that in the second code, the function simply copies the pointer to the stack, and all the changes performed by the function is applied only on the copy? Commented Mar 27, 2013 at 18:57
  • 2
    As a side note, please never use the variable named new (or this or delete). You may think you're never going to convert your code to C++ however if that should happen, you'll make things much easier by avoiding C++'s keywords now. Commented Mar 27, 2013 at 18:57
  • @sid_1607 Quite. The function only changes the copy of the value it got. Commented Mar 27, 2013 at 18:58
  • @mah-Thanks for the advice, I am aware about new,this,delete,etc being c++ keywords. I was just being rather sloppy while coding this. These as variable names seemed simpler. Commented Mar 27, 2013 at 19:00

2 Answers 2

4

Because everything in C is passed by value. So, if you need to assign a new value to an argument to a function, you must add a level of indirection. if you don't you simply receive a local copy, so any value assigned to that copy will be visible only within the function itself.

On a side note, don't cast the return value of malloc in C. It is unnecessary, clutters you code, and can hide an error for compilers which allow default int.

On.. another side note, instead of writing something like:

new_stack = malloc(sizeof(stack));

Use this instead:

new_stack = malloc(sizeof(*new_stack));

Now you don't have a problem if the type of new_stack ever changes.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks!! And yeah the gcc compiler seems to detect casting errors, but yeah the alternate code is definitely seems to be better
2

In case of single pointer say

int addInBeginning(int *s)
{
 ... // add a node in the beginning of the linked list
}

int main()
{
 int *t;
 ... // make t point to a linked list say t ---> 1 -> 2 -> 3
 f(t);
}

Initially, s and t point to the same list. But when we add a node in the beginning, s points to the new node while t still points to the node it was earlier pointing to. When push returns, the new node is inaccessible from t.

0 -> 1 -> 2 -> 3
^    ^
|    |
s    t

In case of double pointer, s will point to t which in turn points to the list. So all pointer manipulations happen on the original pointer t.

s ----> t ----> 0 -> 1 -> 2 -> 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.