user2052197
user2052197

Reputation: 235

C Pointer Assignment in a function

Why can't I assign a point in a function. As you noticed in the following code. I can not assign pointer p1 pointed to the correct address after the function return. But with the global pointer *p, I can store the address information.

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

int *p = NULL;
void test(int * pt1, int**pt2){
    p = (int*)malloc(sizeof(int));    
    pt1 = p;
    *pt2 = p;
    printf("p points to %p\n", p);
    printf("pt1 points to %p\n", pt1);
    printf("pt2 points to %p\n", *pt2);
}

int main(void) {
    int *p1 = NULL; 
    int *p2 = NULL;

    printf("p points to %p\n", p);
    printf("p1 points to %p\n", p1);
    printf("p2 points to %p\n", p2);

    test(p1, &p2);

    printf("p points to %p\n", p);
    printf("p1 points to %p\n", p1);
    printf("p2 points to %p\n", p2);

    return 0;
}

OUTPUT:

p points to (nil)
p1 points to (nil)
p2 points to (nil)
p points to 0x8acb008
pt1 points to 0x8acb008
pt2 points to 0x8acb008
p points to 0x8acb008
p1 points to (nil)
p2 points to 0x8acb008

Upvotes: 5

Views: 5301

Answers (3)

Inside test the variable pt1 is a discrete pointer in its own right. That is to say it is not merely an alias for p1, but rather a copy that exists only for the lifetime of the call.

Thus whatever assignment you make to it is only exits for the duration of that call and is not propagated outside of it. When you return from test the pointer pt1 ceases to exist and any changes aren't copied back.

As well as using an extra "layer" of pointer like you did with pt2 sometimes it's appropriate to use the return value to "share" changes with a wider audience:

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

int *p = NULL;
int *test(int * pt1, int**pt2){
    p = (int*)malloc(sizeof(int));    
    pt1 = p;
    *pt2 = p;
    printf("p points to %p\n", p);
    printf("pt1 points to %p\n", pt1);
    printf("pt2 points to %p\n", *pt2);
    return pt1;
}

int main(void) {
    int *p1 = NULL; 
    int *p2 = NULL;

    printf("p points to %p\n", p);
    printf("p1 points to %p\n", p1);
    printf("p2 points to %p\n", p2);

    p1=test(p1, &p2);

    printf("p points to %p\n", p);
    printf("p1 points to %p\n", p1);
    printf("p2 points to %p\n", p2);

    return 0;
}

Upvotes: 5

William
William

Reputation: 3034

You're passing p1 by value, so it's not updated in the main function. However, you are passing p2 by reference (note that you wrote &p2), so it can be changed.

Upvotes: 1

75inchpianist
75inchpianist

Reputation: 4102

You arre passing the p1 in by value, so the changes are only visable within the scope of that function. pass in a pointer to that pointer, as you did with p2, and you are fine.

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

int *p = NULL;
void test(int **pt1, int**pt2){
    p = (int*)malloc(sizeof(int));    
    *pt1 = p;
    *pt2 = p;
    printf("p points to %p\n", p);
    printf("pt1 points to %p\n", pt1);
    printf("pt2 points to %p\n", *pt2);
}

int main(void) {
    int *p1 = NULL; 
    int *p2 = NULL;

    printf("p points to %p\n", p);
    printf("p1 points to %p\n", p1);
    printf("p2 points to %p\n", p2);

    test(&p1, &p2);

    printf("p points to %p\n", p);
    printf("p1 points to %p\n", p1);
    printf("p2 points to %p\n", p2);

    return 0;
}

Upvotes: 1

Related Questions