Home > Net >  Is passing pointer by value or by reference the same
Is passing pointer by value or by reference the same

Time:01-10

What is the difference between passing a pointer by reference and passing a pointer by value in C?

My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.

When working with pointers I noticed that if I pass a char* by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.

I wrote short code to show what I am talking about.

//test pointer ref
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void passbyval(char const *lit,char* str){
    printf("---passbyval---\n");
    printf("%s\t%p\n",lit,&lit);
    //modify string
    strncat(&str[2],"/",1);
    printf("%s\t%p\n",str, &str);
}
void passbyref(char const **lit, char** str){
    printf("---passbyref---\n");
    printf("%s\t%p\n",*lit,&*lit);
    //modify string 
    strncat(&(*str)[1],"/",1);
    printf("%s\t%p\n",*str,&*str);
}
int main(){

    char const *litstr = "hello this is a test";
    char *str = (char*)malloc(sizeof(char)*100);
    scanf("%[^\n]",str);
    printf("---main---\n");
    //print original value and address
    printf("%s\t%p\n",litstr,&litstr);
    printf("%s\t%p\n",str,&str);
    passbyval(litstr,str);
    //modified value and address from pass by value 
    printf("\nretfromval:%s\t%p\n",str,&str);
    passbyref(&litstr,&str);
    //modified value and address from pass by ref
    printf("\nretfromref:%s\t%p\n",str,&str);
    free(str);
    return EXIT_SUCCESS;
}

Output enter image description here

Is it good practice to not pass by reference char* you want to modify in void methods?

Scratching my head on why I would ever use pass by reference for pointers if the value they are referencing are implicitly passed by reference.

Maybe I'm missing something can some explain this a little better?

CodePudding user response:

When working with pointers I noticed that if I pass a char* by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.

None of your examples do this. Also, none of your code prints the value of litstr or str. To print the values of the pointers, remove the & in all of your printf calls. Then you will see the values of the pointers are the same in the calling routine and the called routine.

In main, printf("%s\t%p\n",litstr,&litstr); prints:

  • the string that starts in memory at the address that is the value of litstr (because of %s and litstr) and
  • the address (not the value) of litstr (because of %p and &litstr).

Similarly, printf("%s\t%p\n",str,&str); prints the string at str and the address of str.

In passbyval, printf("%s\t%p\n",lit,&lit); prints the string at lit and the address of lit. Since lit is a parameter to passbyval, it has its own address, which is different from the address of litstr. If you had printed the values of litstr and lit, instead of their addresses, you would see they are the same.

Similarly, printf("%s\t%p\n",str, &str); prints the string at str and the address of str. The address of the parameter str in passbyval is different from the address of the local object str in main, but their values are the same.

In passbyref, printf("%s\t%p\n",*lit,&*lit); prints the string at lit and the address of *lit. Since lit is the address of the litstr in main, *lit is that litstr, so &*lit is the address of litstr. The value of litstr would be *lit.

Similarly, printf("%s\t%p\n",*str,&*str); prints the string at *str and the address of *str, which is the address of str in main.

CodePudding user response:

What is the difference between passing a pointer by reference and passing a pointer by value in C?

There is no such thing as passing a pointer by reference in C, all variables are passed by value, even pointers.

My understanding is when you pass arguments to methods a new stack frame is created and those values are copied to different memory addresses unless passed by reference. If passed by reference the memory addresses are passed.

Again, the pointers are not passed by reference, a copy of the value stored in the pointer is passed, i.e. the address where it points to, you can test this by changing the value of the pointer inside the function, and check how that reflects on the original pointer, spoiler, it doesn't.

When working with pointers I noticed that if I pass a char by value and modify it in a different stack frame when I return back to the main stack frame the value of the ptr has been modified.*

What you are passing is an address, a memory location where some data is stored, when you change the data stored in that memory address it will be permanent, no matter where you do it, in fact that is one of the advantages of using pointers, for you to change the contents of some variable outside the scope where it's declared.

CodePudding user response:

You need to understand how the pointers and arrays work.

pointer is a separate object having its own reference, holding the reference of the underlying object.

char *p = "aaa";

print("%p\n", (void *)p); //prints the reference of the string literal "aaa"
print("%p\n", (void *)&p); //prints the reference of the pointer `p`

Arrays are contignous chunks of memory. Arrays decay to pointers. Those pointers do not have physical representation in the memory and only are references to the first element of the array.

char p[] = "aaa";

print("%p\n", (void *)p);  //reference of the first element 
                           //of the array p the type is `char *` 
                           //(pointer to char)
print("%p\n", (void *)&p); //reference of the first element of the 
                           //array p the type is `char (*)[4]` 
                           //(pointer to an array of 4 char elements)

CodePudding user response:

What is the difference between passing a pointer by reference and passing a pointer by value in C.

In C, there are various ways arguments are pre-processed before being passed to a function.

  • No processing
    A copy of the argument is given to the function. char *s = ...; puts(s);. puts() is given a copy of s.

  • Usual argument promotion
    The argument is promoted to int, unsigned, double, ... before a copy is given to the function. float fl = 12.5f; printf("%g", fl); printf() is given a copy of double 12.5.

  • Function converted to an address
    With tss_create(tss_t *key, tss_dtor_t dtor);, tss_dtor_t is a function pointer type void (*)(void*). tss_create(... , foo) does not take a function foo() and pass that. Instead a copy of the address of the function is passed.

  • Array converted to address of its first element
    With char s[] = "Hello; puts(s);, A copy of &s[0] is passed to puts().

Now, are any of these like OP's pass by reference?

Yes.

With char *end[1]; strtod("123.4", end);, from the caller's point of view, end is adjusted in it entirety by strtod() and so acts and smells like "pass by reference" from the caller's POV. This is technically still "pass a copy", but the copy is the address of the argument's 1st element.

Other than that, I see no comparable "passing a pointer by reference and passing a pointer by value in C" in which to find a difference.

  •  Tags:  
  • Related