tags:

views:

100

answers:

7
#include <stdio.h>
#include <stdlib.h>

void foo(int *a, int *b);

void foo(int *a, int *b) {
    *a = 5;
    *b = 6;
    a = b;
}

int main(void) {
    int a, b;
    foo(&a, &b);
    printf("%d, %d", a, b);
    return 0;
}

Why a = b (foo) doesn't work? printf outputs "5, 6" Thank you.

+9  A: 

It does work; it just doesn't do what you think it does.

In foo(), a = b changes the pointer a to point to whatever b points to. It has no effect on anything outside of the function; it only changes the pointers.

If you want to change the value of the int pointed to by a to be the same as the value of the int pointed to by b, you need to use *a = *b, similar to how you do the assignments in the function already.

James McNellis
local pointers. Right?
cnoob
@cnoob: Yes. In C, everything is passed by value.
James McNellis
A: 

I'm not sure what you're going after... if it's to get a and b to contain the same value, try *a = *b.

Randolpho
+1  A: 

In foo, a and b are separate local variables. Setting them to have the same value has no effect on the previous values - the last line of foo currently does nothing, basically.

Within foo, a is initially a pointer to the same location as a in main, and b is a pointer to the same location as b in main. The last line just makes the value of a in foo the same as b - namely a pointer to the same location as b in main. So if you add a line

*a = 7;

at the end of foo, then you'd see output of "5, 7".

(Your code would definitely be easier to talk about if you used different variable names in main and foo, by the way.)

If you're trying to make a and b within main "aliased" to each other, you're not going to be successful. They're separate local variables on the stack, and will remain so. You can't make the stack "shrink" to alias the two, whatever you do.

Jon Skeet
A: 

Because when foo is called, the values of the pointers are copied into the function. If you want to change the values of the pointers themselves, you need to pass a pointer to a pointer into the function.

Billy ONeal
Is there another solution. I'm frightened about that!
cnoob
@cnoob: You haven't said what you want to happen, so there's no "solution".
Jon Skeet
sorry. I want to have the output 6, 6 instead of 5, 5.
cnoob
A: 

a and b are local to the function foo (they are on the stack), when program returns from the function data on the stack is lost. when you assign b to a, you are only modifying memory addresses on the stack, not their values.

knittl
+2  A: 

The call to foo() ends with the local variables of foo pointing to the same addres, the one of b. This change is not reflected in main(), the caller.

I you liked to actually do this and make this change pemanent, then you would have to pass a pointer to a pointer to foo() (so you can change them), instead of their simple values:

void foo(int **a, int **b) {
    **a = 5;
    **b = 6;
    *a = *b;
}

I have just observed that your code is incomatible with that modification, anyway, since you cannot change two normal variables to point to each other. You'd have to change it this way:

int main(void) {
    int a, b;
    int * ptrA = &a;
    int * ptrB = &b;
    foo(&ptrA, &ptrB);
    printf("%d, %d (%d, %d)", *ptrA, *ptrB, a, b);
    return 0;
}
Baltasarq
I don't like the look of `int ptrA = ` - did you mean `int *ptrA = `?
Jon Skeet
Yep. Thank you.
Baltasarq
Here it is the same: 5, 6 instead of 6, 6
cnoob
If you show the values of a and b, the int variables, they will remain the same. Show the values of *ptrA and *ptrB and you will get 6,6. This is included in the answer: if you read it thorougly, you will see that the printf() of main() was modified.
Baltasarq
+1  A: 

Using a pseudo-memory map,

In main(),

    a      b
 --------------
|  5   |   6   | <- data
 --------------
 [1000]  [1004]  <- address

In the function foo(),

    a        b      ( local to foo(), different from the a & b in main() )
 ----------------
|  1000  | 1004  | <- data
 ----------------
  [2000]   [2004]  <- address

So, when in foo()'s scope,

*a = 5;   // store 5 in int variable a
*b = 6;   // store 6 in int variable b
 a = b;   // copies contents of pointer variable b to a

So the final map in foo()'s scope is:

    a        b
 ----------------
|  1004  | 1004  | <- data
 ----------------
  [2000]   [2004]  <- address
Kedar Soparkar