Semantics
Semantics

Reputation: 164

Pass by reference for pointers in C

I was trying to understand the concept of passing by reference. When I do this,

#include<stdio.h>
int recent (int *a)
{
    *a = 20;
    return 0;
}
int main()
{
   int bee;
   bee=5;
   int *val = &bee;
   printf("Value is %d\n", *val);
   recent(val);
   printf("Now Value is %d\n", *val);
   return 0;
}

Basically I am making the pointer val point to the memory location of bee, and then when I pass it to recent function, and change the value, that change gets reflected in the calling function, so the value changes to 20. But when I do this,

#include<stdio.h>

int check = 20;

int recent (int *a)
{
    a = &check;
    return 0;
}
int main()
{
   int bee;
   bee=5;
   int *val = NULL;
   recent(val);
   printf("Now Value is %d\n", *val);
   return 0;
}

I get segmentation fault.

Is it because I didn't initialize the pointer to point to any location, and then I passed the value to recent function, and even though I made it point to a memory location (check variable), the calling function didnt catch that because I was passing by value?

Is this completely true or I misinterpreted something and got lucky with the answer?

Upvotes: 0

Views: 109

Answers (6)

chux
chux

Reputation: 153338

Is it because I didn't initialize the pointer to point to any location,

Code well initialized with int *val = NULL;, yet NULL is not a valid location. It isn't the NULL is a location or not. It is the NULL is the null pointer constant. As a null pointer, it "is guaranteed to compare unequal to a pointer to any object or function."

... and even though I made it point to a memory location (check variable), the calling function didn't catch that because I was passing by value?

Yes. With a = &check;, only the local a was affected, not the val in which a was copied from as the actual augment val was passed by value (copied) to the formal parameter a.

Is this completely true ...

IMO: Yes

... I misinterpreted something and got lucky with the answer?

It appears no misinterpretation. Lucky - hard to rate.

Upvotes: 1

user4925
user4925

Reputation: 209

It's basically what all have answered. It's because you are passing the address pointed by pointer a using Pass By Value method. That is your sending in a copy of the address. If you want the second code to work you need to change the code to the following,

#include<stdio.h>

int check = 20;

int recent(int **a)
{
   *a = &check;
    return 0;
}
int main()
{
  int bee;
  bee = 5;
  int *val = NULL;
  recent(&val);
  printf("Now Value is %d\n", *val);

  return 0;
}

That is you have to Pass the address pointed by a by using C version of "Pass By Reference".

Upvotes: 0

F&#225;bio Junqueira
F&#225;bio Junqueira

Reputation: 2781

Here is what is going on in your code:

#include<stdio.h>

int check = 20;

int recent (int *a)
{
    a = &check;
    return 0;
}
int main()
{
   // memory is allocated to hold an integer
   int bee;

   // the number 5 is written into that memory space
   bee = 5; 

   // memory is allocated to hold a memory address
   // the value of null (which is a invalid address) is written into it
   int *val = NULL;

   // more memory is allocated to hold a memory address (int* a)
   // the address in val (which is null) is written into it
   // the new memory address (a) now points to the address of check
   recent(val);

   // val is still NULL
   // BOOOM!
   printf("Now Value is %d\n", *val);

   return 0;
}

Long story short, you are correct! :)

Upvotes: 0

Janek Bevendorff
Janek Bevendorff

Reputation: 608

val is still a null pointer after leaving the function. The pointer itself is (as you correctly guessed) only passed by value, not by reference. Inside the function you are only modifying the pointer (which only lives insides the function), not the pointer target.

Besides that, please be careful with passing around memory locations to automatic stack variables. At least coming from a C++ background, it's considered bad style. Since you don't explicitly control the life cycle of a stack variable yourself (as you would do with malloc/free), you can easily shoot yourself in the foot by accidentally dereferencing pointers which have already been cleaned from the stack.

Upvotes: 1

Tom
Tom

Reputation: 979

Your problem is that you are printing the output of dereferencing the pointer val in the main function. The value of the pointer val in the main function is NULL. Thus the program is trying to print the thing at memory location 0, which is inaccessible to your program and results in a segmentation fault.

First you create the val pointer and assign it the value NULL.

int *val = NULL;

Then you call recent, passing it the pointer val, which still holds NULL.

recent(val);

Finally you print *val. val still holds NULL, and the * operator tells the compiler to "dereference" val, meaning to use the value of the thing that val is pointing to.

printf("Now Value is %d\n", *val);

In response to the question of whether your description is correct, the answer is sort of, but your description is imprecise. You made the function's copy of the pointer point to something. When you implement a pass-by-reference function in C using pointers, you are still passing the pointers themselves by value: a copy of the pointer is made, pushed onto the stack, and sent to the function. If you update the value of the pointer in the called function, the value of the pointer in the calling function will not be changed.

Upvotes: 2

Colin
Colin

Reputation: 11

The reason has to do with your function recent(). When you pass in "a" you are passing in an int* (i.e. int pointer) which is an address to a location in memory. However, "a" as you have it, is local to this function (the pointer is pass by value).

Thus when you set "a = &check", you are only changing the local pointer value. As soon as recent() returns, "a" goes out of scope. In this context, you are never changing what "a" actually points to.

Thus, you segfault because val is still null, and you are trying to dereference a NULL pointer.

Upvotes: 1

Related Questions