clickMe
clickMe

Reputation: 1045

Modify struct via a reference taking function

I want to assign the struct a to the struct b. Printing the address and the values of the array before and after function call it shows that during the function call the assignment works and both pointers point to the same struct address. However, after returning from the function the changes are reversed. Why?

typedef struct arrayA {
    int a[3]; 
}arrayA; 

void f(arrayA *a, arrayA *b){
    a = b; 
    printf("address of a: %p\n", a); 
    printf("address of b: %p\n", b); 
}

int main(int argc, char *argv[]) {
    printf("------------ Array assignment test -----------------\n"); 
    arrayA a = { { 0, 0, 0} }; 
    arrayA b = { { 1, 1, 1} }; 
    printf("address of a: %p\n", &a); 
    printf("address of b: %p\n", &b); 
    printf("a[0] : %d a[1] : %d\n", a.a[0], a.a[1]); 
    f(&a, &b); 
    printf("a[0] : %d a[1] : %d\n", a.a[0], a.a[1]); 
    printf("address of a: %p\n", &a); 
    printf("address of b: %p\n", &b); 
    printf("----------------------------------------------------\n"); 

    return 0;
}

Prints

 ------------ Array assignment test -----------------
address of a: 0x7ffd3fc17b80
address of b: 0x7ffd3fc17b90
a[0] : 0 a[1] : 0
address of a: 0x7ffd3fc17b90
address of b: 0x7ffd3fc17b90
a[0] : 0 a[1] : 0
address of a: 0x7ffd3fc17b80
address of b: 0x7ffd3fc17b90
----------------------------------------------------

Upvotes: 0

Views: 447

Answers (2)

user1952500
user1952500

Reputation: 6771

You are passing the pointers by value and expecting them to get modified. They will be modified within the function as there is a copy of the pointer (address) that is made local to the function. When the function returns the originals remain unchanged. (You could try to print the address of the local variables within the function to understand better.)

If you want to change the structs, you'll want to dereference the pointers:

void f(arrayA *a, arrayA *b){
    *a = *b; 
    printf("address of a: %p\n", a); 
    printf("address of b: %p\n", b); 
}

If you want to change the pointers themselves, you'll need an extra indirection:

void f(arrayA **a, arrayA **b){ // Note the ** here
    *a = *b; 
    printf("address of a: %p\n", a); 
    printf("address of b: %p\n", b); 
}

Upvotes: 2

tdao
tdao

Reputation: 17668

However, after returning from the function the changes are reversed. Why?

Your f() function really just change the pointer inside it, and those pointer changes are not reserved after the function.

You can copy struct by pass-by-pointer:

void f(arrayA *a, arrayA *b){
    *a = *b; 
}

That will ensure you can copy struct in main() via

f(&a, &b); 

As all you need is copy struct, there is no need to print out the addresses at all. In case you do need to debug the address, you should convert to (void *) to avoid all the warnings with printf("%p")

Upvotes: 1

Related Questions