C pointer referencing another pointer in functions - c

I discovered that if you assign a pointer address to another pointer's address in a FUNCTION it won't change the in value in the main,
however by doing the same thing in main, it will change. So what is the reason of this?
void func(int *a, int *b){
b = a;
}
int main(){
int i= 5, k =6, *a=&i, *b=&k;
printf("%d %d\n",*a,*b); //output 5 6
b = a;
printf("%d %d\n",*a,*b); //output 5 5
a=&i;
b=&k;
func(a,b);
printf("%d %d\n",*a,*b); //output 5 6
printf("%d %d\n",*a,*b); //output 5 6
}

In this function
void func(int *a, int *b){
b = a;
}
parameters a and b are local variables of the function. After exiting the function they will be destroyed. The function deals with copies of arguments. If you want that the function would change the original arguments themselves you have to pass pointers to them. For example
void swap(int **a, int **b){
int *tmp = *a;
*a = *b;
*b = tmp;
}

Your function:
void func(int *a, int *b){
b = a;
}
doesn't do anything, it just takes two values representing memory addresses as parameters and assigns one to the other without any external effect whatsoever. It just writes the value of the one to the other (probably not even that, because the compiler will likely detect this is pointless and eliminate it altogether), it doesn't do anything with the information stored at those addresses. You will need to deference the pointer to read or write to the memory address it holds the value of, but in the present form, the function will not assign the pointer to the other, but the value of i to k.
If you want a function to change a parameter outside of it, you should pass by reference, which in C is just pass by pointer, so you need to pass a pointer to the pointer, not the pointer - which will pass a copy of that pointer - the same value, while passing as pointer to pointer will pass the address of the pointer in memory, not the value it holds.
So it should be:
void func(int **a, int **b){
*b = *a;
}
and func(&a,&b) and you will reproduce what you do in main via b = a.

Related

Pointer value in c

Generally speaking, a pointer's value inside a function in c is local or can be accessed in main through the pointer?
Example code:
size_t *function(int a, int *b)
{
int d;
size_t *array;
b = &d;
//DO STUFF HERE
printf("%d", *b); //This gets printed right
return array;
}
int main()
{
size_t *array2;
int *b;
array2 = function(a, b);
printf("%d", *b); //This gives seg fault
}
Arguments are local variables, so you are not actually assigning to main's pointer, you are just ignoring the value passed as argument and assigning to the local b in function. You need a pointer to pointer int **b argument in order to assign to the b in main.
Also, the assigned address is that of a local variable d, which ceases to exist when function returns so accessing it afterwards through a pointer would be invalid regardless (undefined behaviour, even if it might happen to work before it gets overwritten on the stack).
edit: If your goal is to get the value of d to main, you don't need a pointer in main, so instead of b you can have int d in main and pass its address &d to function (function(a, &d)), then you can assign to main's d in function with *b = d.
In function main you pass the pointer b to function but b is uninitialized (can contain any value):
array2 = function(a, b);
Thefore this makes no sense. Inside function, If you want to modify b you need to instead call function like this:
int b;
array2 = function(a, &b);
The function can now assign to *b.
As Arkku says Arguments are local variables, you can treat the pointer as an address value like 0x7fff13f1ce3c, then it's pretty easy to understand.
typedef address int*
typedef address2 size_t*
size_t *function(int a, address b)
{
int d;
address2 array;
b = &d;
//DO STUFF HERE
printf("%d", *b); //This gets printed right
return array;
}
int main()
{
address2 array2;
address b;
array2 = function(a, b);
printf("%d", *b); //This gives seg fault
}
Change the value of b in function won't influence the value of b in main. As for the array, function will return An address value.

C - Pass structure pointer VS integer pointer to functions

void main(){
int a = 100;
int* pa = &a;
*pa = 999;
}
The above code will make the value of a to 999. But why not the pointers to structures treated the same way?
struct node* head = (struct node*) malloc(sizeof(struct node));
head -> data = 6;
head -> next = NULL;
Why can we not use *head -> data = 6? And why passing someMethod(pa) is pass by reference and someMethod(head) is pass by value? reference
Why can we not use *head -> data = 6?
Because -> is a dereference operator that replaces the asterisk *. You can rewrite with an asterisk, too
(*head).data = 6
You need parentheses because dot has higher precedence than indirection. Operator -> has been introduced to make indirection more readable in case of pointers to structs.
why passing someMethod(pa) is pass by reference and someMethod(head) is pass by value?
It's all pass by value, because pointers are passed by value, too. Passing a pointer lets you reference the original variable and modify it, but the pointer itself is copied.
First question's answer, you have got already.
For second Question, Consider three variables, A,B,C where A & C are integer Variables and B is a integer Pointer. Variable names, their values and address(assumed to see a memory map)
has been shown in picture.
see this code
void fun(int *b,int *c)
{
printf("\nfun %d",*b);
b=c;
}
void fun1(int **b, int *c)
{
printf("\nfun1 %d",**b);
*b=c;
}
int main()
{
int a=10;
int c=200;
int *b=&a;
printf("\n %d %d %d",a,*b,c);
fun(b,&c);
printf("\n %d %d %d",a,*b,c);
fun1(&b,&c);
printf("\n %d %d %d",a,*b,c);
return 0;
}
In main(),a & c are local integer Variables, having different data and b is a integer pointer. We are calling function fun() like this,
fun(b,&c);
Since, b is a pointer so, we are passing the value of b i.e address of a (1000).
so if we modify the b inside function fun(), that change will reflect inside the fun() only.
Now we call the function fun1(),
fun1(&b,&c)
Here, we are passing the address of b i.e (3000). so, when we modify the b inside the fun1() , we see the reflection in main() as well.
so, passing by value means, we want to use values without modifying the original pointer present in calling function( main() ). but we pass by reference, when we need any significant change which should reflect in our calling function( main() ) itself.
I hope, this clears the doubt.

why use Pointer on single variable

please explain exactly why do i use pointer on non array variable such as int i know pointer variable store the address of specified variable but why do we need address of just single variable, what is the advantage of doing this?
int a = 10;
int *ptr_a = &a;
Thanks!
Although I guess the code you're looking at should give you an answer ... the typical reason this is done is for passing it to a function that should be able to modify this variable.
if you just call foo(a), the function foo() will receive the value of the variable as an argument, so it has it's own copy. The same thing happens with a pointer, but the pointer will of course still point to your original variable, so the function could modify it by dereferencing the pointer (*a = 42;).
By using pointer we achieve call by reference mechanism
please compile below snippet by removing the pointer and note the output.
#include <stdio.h>
void swap(int *a,int *b);
int main(){
int num1=5,num2=10;
swap(&num1,&num2); /* address of num1 and num2 is passed to swap function */
printf("Number1 = %d\n",num1);
printf("Number2 = %d",num2);
return 0;
}
void swap(int *a,int *b){ /* pointer a and b points to address of num1 and num2 respectively */
int temp;
temp=*a;
*a=*b;
*b=temp;
}
Explanation:
The address of memory location num1 and num2 are passed to function and the pointers *a and *b accept those values. So, the pointer a and b points to address of num1 and num2 respectively. When, the value of pointer are changed, the value in memory location also changed correspondingly. Hence, change made to *a and *b was reflected in num1 and num2 in main function.
This technique is known as call by reference in C programming.

C pointers - Point to the same address

#include <stdio.h>
#include <stdlib.h>
void foo(int *a, int *b);
void foo(int *a, int *b) {
*a = 5;
*b = 6;
a = b;
}
int main(void) {
int a, b;
foo(&a, &b);
printf("%d, %d", a, b);
return 0;
}
Why a = b (foo) doesn't work? printf outputs "5, 6"
Thank you.
It does work; it just doesn't do what you think it does.
In foo(), a = b changes the pointer a to point to whatever b points to. It has no effect on anything outside of the function; it only changes the pointers.
If you want to change the value of the int pointed to by a to be the same as the value of the int pointed to by b, you need to use *a = *b, similar to how you do the assignments in the function already.
The call to foo() ends with its local variables pointing to the same addres, the one of stored in b. This change is not reflected in main(), the caller.
I you liked to actually do this and make this change pemanent, then you would have to pass a pointer to a pointer to foo() (so you can change them), instead of their simple values:
void foo(int **a, int **b) {
**a = 5;
**b = 6;
*a = *b;
}
I have just observed that your code is incompatible with that modification, anyway, since you cannot change two normal variables to point to each other. You'd have to also modify main() this way:
int main(void) {
int a, b;
int * ptrA = &a;
int * ptrB = &b;
foo(&ptrA, &ptrB);
printf("%d, %d (%d, %d)", *ptrA, *ptrB, a, b);
return 0;
}
Using a pseudo-memory map,
In main(),
a b
--------------
| 5 | 6 | <- data
--------------
[1000] [1004] <- address
In the function foo(),
a b ( local to foo(), different from the a & b in main() )
----------------
| 1000 | 1004 | <- data
----------------
[2000] [2004] <- address
So, when in foo()'s scope,
*a = 5; // store 5 in int variable a
*b = 6; // store 6 in int variable b
a = b; // copies contents of pointer variable b to a
So the final map in foo()'s scope is:
a b
----------------
| 1004 | 1004 | <- data
----------------
[2000] [2004] <- address
In foo, a and b are separate local variables. Setting them to have the same value has no effect on the previous values - the last line of foo currently does nothing, basically.
Within foo, a is initially a pointer to the same location as a in main, and b is a pointer to the same location as b in main. The last line just makes the value of a in foo the same as b - namely a pointer to the same location as b in main. So if you add a line
*a = 7;
at the end of foo, then you'd see output of "5, 7".
(Your code would definitely be easier to talk about if you used different variable names in main and foo, by the way.)
If you're trying to make a and b within main "aliased" to each other, you're not going to be successful. They're separate local variables on the stack, and will remain so. You can't make the stack "shrink" to alias the two, whatever you do.
I'm not sure what you're going after... if it's to get a and b to contain the same value, try *a = *b.
Because when foo is called, the values of the pointers are copied into the function. If you want to change the values of the pointers themselves, you need to pass a pointer to a pointer into the function.
a and b are local to the function foo (they are on the stack), when program returns from the function data on the stack is lost. when you assign b to a, you are only modifying memory addresses on the stack, not their values.

Simple swap function...why doesn't this one swap?

I'm new to C and still trying to grasp the concept of pointers. I know how to write a swap function that works...I'm more concerned as to why this particular one doesn't.
void swap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(a, b);
printf(ā€œ%d %d\nā€), *a, *b);
}
You're missing *s in the swap function. Try:
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
That way, instead of just swapping the pointers, you're swapping the ints that the pointers are pointing to.
Your swap() function does work, after a fashion - it swaps the values of the variables a and b that are local to swap(). Unfortunately, those are distinct from the a and b in main() - so you don't actually see any effect from swapping them.
When thinking about pointers, you need to be clear on a few abstractions.
An object in memory. This can be of any type (and size). An integer object, for example, will occupy 4 bytes in memory (on 32 bit machines). A pointer object will occupy 4 bytes in memory (on 32 bit machines). As should be obvious, the integer object holds integer values; a pointer object holds addresses of other objects.
The C programming language lets symbols (variables) represent these objects in memory. When you declare,
int i;
the symbol (variable) i represents some integer object in memory. More specifically, it represents the value of this object. You can manipulate this value by using i in the program.
&i will give you the address of this object in memory.
A pointer object can hold the address of another object. You declare a pointer object by using the syntax,
int* ptr;
Just like other variables, the pointer variable represents the value of an object, a pointer object. This value just happens to be an address of some other object. You set the value of a pointer object like so,
ptr = &i;
Now, when you say ptr in the program, you are referring to its value, which is the address of i. But if you say *ptr, you are referring to not the value of ptr, but rather the value of the object whose address is in ptr i.e. i.
The problem with your swap function is that you are swapping values of pointers, not the values of objects that these pointers hold addresses for. To get to the values of objects, you would have to use *ptr.
C is a pass-by-value language. Your swap routine doesn't dereference the pointers passed to it, so from main's perspective nothing has happened.
The pointers are passed by value. This means a & b are still a and b when the come back from the function;
try something like this
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
The right way to do it:
void swap(int* a, int* b)
{
int temp = *a; // Temp is set to the value stored at a (5)
*a = *b; // value stored at a is changed to the value stored at b (10)
*b = temp; // value stored in address b is changed to 5.
}
It does swap. It swaps local pointers a and b inside swap function. It swaps them perfectly fine, as it should.
If you want to swap the values these pointers are pointing to, you should re-implement your swap function accordingly, i.e. make it swap the pointed values, not the pointers.
Umm maybe using this
void swap(int** a, int** b)
{
int** temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(&a, &b);
printf(ā€œ%d %d\nā€), *a, *b);
}
Without using a third variable (temp)
void swap(int* a,int* b)
{
// a = 10, b = 5;
*a = *a + *b; // a now becomes 15
*b = *a - *b; // b becomes 10
*a = *a - *b; // a becomes 5
}
zildjohn1's answer is the easiest and clearest way to do it. However if you insist on swapping the pointers, then you have to pass the pointer to the pointer because the pointer itself is passed by value.
You need to send the address of a and b for swap function so while calling swap function you must call ass swap (&a,&b)
So that you pass the address, and alter the address
#define SWAP(a,b) ((a)=(b)+(a),(b)=(a)-(b),(a)=(a)-(b))
Works good.

Resources