I have a collection with values and I want to assign a pointer to point to one of the item in the collection.
Here is a similar example which does not work:
void changeVar(int * var) {
int newInteger = 99;
var = &newInteger;
}
int main() {
// create a random pointer and initialize to NULL
int * randomPointer= 0;
// the printf prints out it's address as 0. good.
printf("address: %d \n\r", randomPointer);
// pass the pointer to a function which should change where the pointer points
changeVar(randomPointer);
// the printf below should print the value of the newInteger and randomPointer should point to newInteger value address
printf("value: %d \n\r", *randomPointer);
return 0;
}
How do I make so that after the changeVar function, the randomPointer points to the address of newInteger?
PS. randomPointer must be a pointer
To make the change to var propagate back to the caller, you need to pass var by pointer:
void changeVar(int** var) {
(*var) = ...;
}
That said, newInteger goes out of scope the moment changeVar returns, so you shouldn't keep pointers to it after that. Dereferencing such a pointer would result in undefined behaviour.
You need to pass a reference (a pointer to a pointer) to your function. In that way you can tell the function "change the value at this location".
void changeVar(int **pp){
static int n=99;
*p = &n;
}
Note - you need static because the memory location will otherwise be invalid once you leave the function. Now you call it with
changeValue(&randomPointer);
Related
How does the C compiler understand whether the given function does a pass by value or pass by reference?
what will happen if the pointer of a variable is passed as integer (as pass by value) to a function ? OR is this possible in C ?
ie: the address of a variable is copied to another variable(int) and that variable is passed to a function. here the called function will get an address as normal integer parameter. Is this possible in C? if not why?
In C it is possible only the pass by value (by reference is supported only in C++).
Both a standard variable and a pointer variable are passed by value. So, the compiler must not make any check about reference or value.
standard variables and pointer variables are same, both store values, but a pointer variable can store only an address value and supports the dereferencing operator '*', this operator get the value pointed by the pointer variable.
Thanks to this, when you pass by value (C support only by value) a pointer variable, the value of the pointer variable is copied in a local pointer variable (instanced in the function stack) this variable is the pointer argument of the function. So you can access to address value copied in the local pointer variable using the dereferencing operator.
Added comments 08/22/14
I can better explain with a example:
void FuncSet10(int* PtrArgument)
{
// The PtrArgument is a local pointer variable
// it is allocated in the stack. The compiler
// copies the MyIntVariable address in this variable
// Using dereferencing operator I can access to
// memory location pointed by PtrArgument
*PtrArgument = 10;
}
void FuncSet20(int IntArgument)
{
// The IntArgument is a local variable
// allocated in the stack. The compiler
// copies the MyIntVariable address in this variable
// this code emulates the dereferencing operator
// and so poiter mechanism.
*((int*)IntArgument) = 20;
}
void FuncMovePointer(int* pointer)
{
int a = *pointer++; // now a contains 1
int b = *pointer++; // now b contains 2
int c = *pointer++; // now c contains 3
printf("a contains %d\n", a);
printf("b contains %d\n", b);
printf("c contains %d\n", c);
// The *Ptr now points to fourth (value 4) element of the Array
printf("pointer points to %d\n", *pointer);
}
int _tmain(int argc, _TCHAR* argv[])
{
int Array[] = {1, 2, 3, 4}; // Array definition
int* pointer = Array; // pointer points to the array
int MyIntVariable;
// First example for explanation of
// the pointer mechanism and compiler actions
// After calling this function MyIntVariable contains 10
FuncSet10(&MyIntVariable);
printf("MyIntVariable contains %d\n", MyIntVariable);
// After calling this function MyIntVariable contains 20
// This code emulate pointer mechanism
FuncSet20((int)&MyIntVariable);
printf("MyIntVariable contains %d\n", MyIntVariable);
// Second example to demonstrate that a pointer
// is only a local copy in a called function
// Inside function the pointer is incremented with ++ operator
// so it will point the next element before returning by function
// (it should be 4)
FuncMovePointer(pointer);
// But this is not true, it points always first element! Why?
// Because the FuncMovePointer manages a its local copy!
printf("but externally the FuncMovePointer it still points to first element %d\n", *pointer);
return 0;
}
I hope that above code can help better your understanding.
Angelo
How does the C compiler understand whether the given function does a
pass by value or pass by reference?
For your information C not understand about pass by reference. You can send pointer to variable.
what will happen if the pointer of a variable is passed as integer (as
pass by value) to a function ?
Passing the pointers to a variable and the accessing it using dereferencing within the function.So By passing a pointer to a function you can allow that function to read and write to the data stored in that variable.
For example
void myfunc( int *myval ) // pointer "myval" point address of "locvar"
{
*myval = 77; //place value 77 at address pointed by "myval"
}
int main()
{
int locvar=10; //place value 10 at some address of "locvar"
printf("locvar = %d\n",locvar);
myfunc(&locvar); // Here address of "locvar" passed
printf("locvar = %d\n",locvar);
return 0;
}
Hello I am a beginner in C programming language. Recently I read about call by value and call by address. I have learned that in call by address changes in the called functions reflects the callee. However the following code does not work like that.
int x = 10,y = 20;
void change_by_add(int *ptr) {
ptr = &y;
printf("\n Inside change_by_add\t %d",*ptr);
// here *ptr is printing 20
}
void main(){
int *p;
p = &x;
change_by_add(p);
printf("\nInside main\t %d", *p);
// here *p is still pointing to address of x and printing 10
}
When I am passing address then why the changes made by called function does not reflect caller?
The function is assigning a new address to the pointer but the pointer itself is being passed by value, as all arguments are in C. To change the value of a pointer variable the address of the pointer itself must be passed:
void change_by_add(int **ptr)
{
*ptr = &y;
}
change_by_add(&p);
See C FAQ Question 4.8.
Passing by reference does not exist in C but can be achieved by passing the address of the variable who's value is to be changed to a function. For example:
void add_to_int(int* a_value, int a_increment)
{
*a_value += a_increment;
}
You are simply setting the value of the pointer in the function, not the value of the pointed to variable. The function should use the following code:
*ptr = y;
This derefences the pointer (exposing the value pointed to), and therefore when you use the equals operator, the memory pointed at is modified, not the pointer itself. I hope this helps to clarify things.
Changes made by called function does not get reflected by the caller because you are overriding the pointer address in the called function i.e ptr = &y;.
Initially, you passed the address of x but you are changing it with the address of y.
If you really want to implement the concept of call by address then change value instead of address.
Example:
void change_by_add(int *ptr) {
*ptr = y; //changing value
printf("\nInside change_by_add\t %d",*ptr);
}
void main(){
int *p;
p = &x;
change_by_add(p);
printf("\nInside main\t %d \n", *p);
return 0;
}
Output
Inside change_by_add 20
Inside main 20
There is no such thing as call by address in C. There is only call by value. What one does when a function needs to modify an argument in a way that is visible to the caller is to have the caller pass a pointer to something, and have the called function write the update though that pointer. Note that the pointer itself is still sent as call-by-value - that is: the called function gets its own copy of the pointer and could change it to point to anything else if it wants to.
I'm new to C and I have a doubt.
Since C functions create local copies of it's arguments, I'm wondering why the following code works as expected:
void function(int array[]){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}
int main(){
int array[] = {1,2,3};
function(array);
printf("%d %d %d",array[0],array[1],array[2]);
return 0;
}
With the line output being 4 5 6.
Why does this work while the following doesn't?
void function(int integer){
integer = 2;
}
int main(){
int integer = 1;
function(integer);
printf("%d",integer);
return 0;
}
The output is just 1 in this case.
Short version: Why can functions modify the values of their parent variables if they are passed as array?
Thank you all!
This is caused by the fact that arrays tend to decay into pointers.
int a[] = { 1, 2, 3 };
int* p = a; // valid: p is now the address of a[0]
a = p; // NOT valid.
printf("a = %p\n", a);
printf("p = %p\n", p); // prints same address as a
a and p will print the same value.
Contrary to what others have said, a is not a pointer, it can simply decay to one. http://c-faq.com/aryptr/aryptrequiv.html
In your first function() what gets passed is the address of the array's first element, and the function body dereferences that. Infact, the compiler is treating the function prototype as this:
void function(int* array /*you wrote int array[]*/){
array[0] = 4;
array[1] = 5;
array[2] = 6;
}
function(&array[0]);
This has to happen because you said "array of unknown size" (int array[]). The compiler could not guarantee to deduce the amount of stack required to pass by value, so it decays to a pointer.
---- Edit ----
Lets combine both your examples and use more distinctive names to make things clearer.
#include <stdio.h>
void func1(int dynArray[]) {
printf("func1: dynArray = %p, &dynArray[0] = %p, dynArray[0] = %d\n",
dynArray, &dynArray[0], dynArray[0]);
}
void func2(int* intPtr) {
printf("func2: intPtr = %p, &intPtr[0] = %p, intPtr[0] = %d\n",
intPtr, &intPtr[0], intPtr[0]);
}
void func3(int intVal) {
printf("func3: intVal = %d, &intValue = %p\n",
intVal, &intVal);
}
int main() {
int mainArray[3] = { 1, 2, 3 };
int mainInt = 10;
printf("mainArray = %p, &mainArray[0] = %p, mainArray[0] = %d\n",
mainArray, &mainArray, mainArray[0]);
func1(mainArray);
func2(mainArray);
printf("mainInt = %d, &mainInt = %p\n",
mainInt, &mainInt);
func3(mainInt);
return 0;
}
Live demo at ideone: http://ideone.com/P8C1f4
mainArray = 0xbf806ad4, &mainArray[0] = 0xbf806ad4, mainArray[0] = 1
func1: dynArray = 0xbf806ad4, &dynArray[0] = 0xbf806ad4, dynArray[0] = 1
func2: intPtr = 0xbf806ad4, &intPtr[0] = 0xbf806ad4, intPtr[0] = 1
mainInt = 10, &mainInt = 0xbf806acc
func3: intVal = 10, &intValue = 0xbf806ad0
In func1 and func2 "dynArray" and "intPtr" are local variables, but they are pointer variables into which they receive the address of "mainArray" from main.
This behavior is specific to arrays. If you were to put the array inside a struct, then you would be able to pass it by value.
An array passed to a function is converted to a pointer. When you pass a pointer as argument to a function, you simply give the address of the variable in the memory. So when you modify the value of the cell of the array, you edit the value under the address given to the function.
When you pass a simple integer to a function, the integer is copied in the stack, when you modify the integer within the function, you modify the copy of the integer, not the original.
Reminder of the different kinds of memory in C
In C, we can use three types of memory :
the stack, used for local variables and functions calls: when we create a variable in main(), we use the stack to store the variable, and when a function is called, the parameters given to the method are register in the stack. When we exit a function, we "pop" these parameters to return to the original state, with the used variable before the call of the function. (anecdote: a stackoverflow is when we hack the stack to use previous variables in a function without passing it as parameters)
the heap which corresponds to the dynamicly allocated memory: when we need large amount of data, we use this heap because the stack is limited to a few megabytes.
the code where the program instructions are stored
In the case of this array passed by a function, which is a pointer (address to an other variable), it is stored in the stack, when we call the function, we copy the pointer in the stack.
In the case of the integer, it is also stored in the stack, when we call the function, we copy the integer.
If we want to modify the integer, we can pass the address of the integer to modify the value under the pointer, like this:
void function(int *integer)
{
*integer = 2;
}
int main()
{
int integer = 1;
function(&integer);
printf("%d", integer);
return 0;
}
There is a difference between 'pass by reference' and 'pass by value'
Pass by reference leads to a location in the memory where pass by value passes the value directly, an array variable is always an refference, so it points to a location in the memory. Integers will pass by value by default
In the first code, you are passing the address of the array pointing to the top element in the array. So, when you modify the value in the function and return to the main function you are still accessing the same array which is in the same address. This is called pass by reference.
However, in the second case, the value of the integer is copied from the main function to the called function. In other words, the two integers are in different address in the memory. So modifying one does not modify the other.
The array name is a pointer to the first element in the array. In the first code sample you have passed a pointer to the memory location containing the first array element. In the second code sample you have passed an integer by value so it has nothing to do with the local variable named "integer"
check that link
Pass by reference and pass by value
Pass by Reference / Value in C++
Can someone explain / give a reasoning to me on why the value of variable i in main function in below code snippet does not change via function test1 while it does change via test2? I think a single pointer should be sufficient to change the value of i. Why are we supposed to use double pointer?
#include <stdio.h>
void test1(int* pp)
{
int myVar = 9999;
pp = &myVar;
}
void test2(int** pp)
{
int myVar = 9999;
*pp = &myVar;
}
int main()
{
printf("Hej\n");
int i=1234;
int* p1;
p1 = &i;
test1(p1);
printf("does not change..., p1=%d\n",*p1);
test2(&p1);
printf("changes..., p1=%d\n",*p1);
return 0;
}
In C parameters are passed by value. This means that in test1 when you pass pp a copy is made of the pointer and when you change it the change is made to the copy not the pointer itself. With test2 the copy is of a double pointer but when you dereference and assign here
*pp = &myVar;
you are changing what is being pointed to, not changing pp itself. Take note that this behaviour in test2 is undefined as is documented in some of the other answers here
But you're not changing the value of i, you're changing the address that pp points to, if you only want to change the value of i then it's enough to change your test to:
void test3(int* pp)
{
int myVar = 9999;
*pp = myVar;
}
If you want to change the value of a variable of type T you have to use a pointer on that type (T*). Since you want to change a pointer (T = int*), you have to provide a pointer to a pointer (T* = int**), otherwise you're only going to change the copy.
Note that
int myVar = 9999;
*pp = &myVar;
will result in undefined behavior, since pp will now contain the address of a local variable which isn't valid after you exit the function.
Because f(x) can't change the value of x, no matter whether x is an int, a float, or a pointer.
void test1(int* pp)
{
int myVar = 9999;
pp = &myVar;
}
This function is passed a pointer pp. The function modifies that pointer. But since parameters are passed by value, that modification is not seen by the caller.
You need to write the function like this:
void test1(int* pp)
{
*pp = 9999;
}
The caller of this function is expected to pass the address of an int variable. The function then writes an int value, 9999 in this case, to that address. This is the key. You are passed an address, and you then write a value to that address. Your broken version simply modified the address. You were missing the indirection.
When the function returns, the caller can observe the modification to the int variable whose address was passed to the function. The calling code can look like this:
int i = 0;
test1(&i); // pass address of int variable
printf("%d\n", i); // prints the new value, 9999
void test2(int** pp)
{
int myVar = 9999;
*pp = &myVar;
}
Now, this is broken in a very serious way. This function does indeed return a pointer to the caller. But it returns a pointer to an object that goes out of scope as soon as the function returns. That is known as undefined behaviour. Don't do this. Never pass out of a function, a pointer to a local variable defined in that function.
pp = &myVar; assigns the address of myVar to the pointer pp. If you want to change the value that pp points to, use
*pp = myVar;
instead.
In answer to your second question, pass a pointer to a pointer when you want to change the object pointed to rather than changing the value of your existing object.
int* p1;
p1 = &i;
test1(p1); //1st
test2(&p1); //2nd
In simple way , 1st is pass by value and 2nd is pass by address.
Description :
In first case it passing pointer is actually the copy of that p inside test1 so the pp inside test1 is the local to that function and it's created in test1. You assigned the address and when comes out of function it's destroyed.
But in second case you are passing the address of the pointer to test2 function. So the pointer pp in test2 will point to the pointer p in main so assigning a new address to pp using *pp = &myVar will automatically set the value of p(since you are dereferencing the pointer). Hence when test2 terminates still p will point to modified location.
" Double pointers are also sometimes employed to pass pointers to functions by reference "
can somebody can explain me the above statement, what exactly does point to function by reference means ?
I believe this example makes it clearer :
//Double pointer is taken as argument
void allocate(int** p, int n)
{
//Change the value of *p, this modification is available outside the function
*p = (int*)malloc(sizeof(int) * n);
}
int main()
{
int* p = NULL;
//Pass the address of the pointer
allocate(&p,1);
//The pointer has been modified to point to proper memory location
//Hence this statement will work
*p=10;
//Free the memory allocated
free(p);
return 0;
}
It means that you have a function that takes a pointer pointer (type int ** for example). This allows you to modify the pointer (what data it is pointing to) much in the way passing a pointer by reference would allow.
void change (int *p) {*p = 7;}
void Really_Change (int **pp) {*pp = null;}
int p = 1;
int *pp = &p;
// now, pp is pointing to p. Let's say it has address 0x10;
// this makes a copy of the address of p. The value of &p is still 0x10 (points to p).
// but, it uses that address to change p to 7.
change(&p);
printf("%d\n", p); // prints 7;
// this call gets the address of pp. It can change pp's value
// much like p was changed above.
Really_Change(&pp);
// pp has been set to null, much like p was set to 7.
printf("%d\n", *pp); // error dereference null. Ka-BOOM!!!
So, in the same way that you can pass a pointer to an int and change the value, you can pass a pointer to a pointer and change its value (which changes what it points to.)
I'll try to explain with both code and plain english :). The explanation may get long, but it will be worth the while.
Suppose we have a program, running its main() function, and we make a call to another function that takes an int parameter.
Conceptually, When you pass a variable as a parameter to a function, you can do so in (roughly speaking) two ways: by value, or by reference.
"By value" means giving the function a copy of your variable. The function will receive its "content" (value), but it won't be able to change the actual variable outside its own body of code, because it was only given a copy.
"By reference", on the other hand, means giving the function the actual memory address of our variable. Using that, the function can find out the variable's value, but it can also go to that specified address and modify the variable's content.
In our C program, "by value" means passing a copy of the int (just taking int as argument), and "by reference" means passing a pointer to it.
Let's see a small code example:
void foo(int n) {
n = 10;
printf("%d\n", n);
}
int main() {
int n = 5;
foo(n);
printf("%d\n", n);
return 0;
}
What will the output of this program be? 10 10? Nope. 10 5! Because we passed a copy of the int, by value and not by reference, foo() only modified the number stored in its copy, unable to reach main()'s copy.
Now, if we do it this way:
void foo(int* n) {
*n = 10;
printf("%d\n", *n);
}
int main() {
int n = 5;
foo(&n);
printf("%d\n", n);
return 0;
}
This time we gave foo() our integer by reference: it's actual memory address. foo() has full power to modify it by accessing it's position in memory, foo() and main() are working with the same copy, and so the output will be 10 10.
As you see, a pointer is a referece,... but also a numerical position in memory. It's similar to an int, only the number contained inside is interpreted differently. Think of it this way: when we pass our int by reference, we're passing an int pointer by value!. So the same by value/by reference logic can be applied to pointers, even though they already are references.
If our actual variable was not an int, but an int reference (pointer), and we wanted main() and foo() to share the same copy of that reference so that foo() can modifiy it, what would we do? Why of course, we'd need a reference to our reference! A pointer to a pointer. That is:
int n; /* integer */
int* n; /* integer reference(pointer). Stores an int's position in memory */
int** n; /* reference to integer reference, or double pointer.
Stores int*'s memory address so we can pass int*s by reference. */
I hope this was useful.