Pointer and address issue in C - c

Suppose that in the main function an int type varaible x has a value 20. IF the function is called 2 times as foo(&x) , whats the value of x?
#include<stdio.h>
void foo(int *n)
{
int *m;
m = (int *)malloc(sizeof(int));
*m = 10;
*m = (*m)*5;
n = m;
}
int main()
{
int x = 20;
foo(&x);
printf("%d",x);
}
Shouldn't the value of x be 50 since we are initializing the address of n with m which has the value 50 but its coming out to be 20?

The address of the n pointer is local to foo. So modifying the pointer inside foo has no effect outside of the function. But when dereferencing n, the pointed-to value can be changed.
For x to become 50, the last line of the foo function should have been:
*n = *m;

Related

Scope of a pointer in memory

I have been studying C for the past weeks, but I can't fully understand how memory manages pointers.
My question arises from this example obtained from here(page 17 of 19): C-Pointer-Basics
Example code:
#include <stdio.h>
void F(int, int *);
int main()
{
int m = 3;
int n = 5;
F(m, &n);
printf("main: %d, %d\n", m, n); // print 3 7 (Where does the 7 came from?)
return 0;
}
void F(int a, int *b)
{
/*
* `a` being a local variable, gets cleaned after `F()` ends
* BUT how does `b` retain the value of `&a`?
*/
a = 7;
*b = a; // `*b = 7`
b = &a; // `b` points to `a`
*b = 4; // `a = 4` and why `*b` doesn't return 4?
printf("F: %d, %d\n", a, *b); // print 4 4
}
The question here is:
Why when main() prints the values of m and n, It showsm = 3 and n = 7?
My assumptions:
As I know, a pointer goes beyond the scope of the function where it is declared, so in void F(int a, int *b) when the function is no longer needed, it gets destroyed, same with his parameters, BUT the value of int *b remains in memory right(even though int *b no longer exists)? So if this is true, we can 'recover' it from memory and use it in main().
Best,
For the question why m and n print 3,7 is because the first parameter is passed by value hence it is only getting copied, therefore no modification of the original m is happening and in the case of n, you're passing its address so when you do *b=a the value of a gets copied to n. And then when you do b=&a the pointer b now starts pointing to the address of a instead of that of n. Which is why the second time you do *b=4, you are not modifying n but a.

int are mutable in C. What is the purpose of using pointer to change the value of mutable object?

Can anyone explain me the difference among these two?
#include <stdio.h>
void main() {
int a = 10;
int *p = &a;
*p = 11;
}
and
#include <stdio.h>
void main() {
int a = 10;
a = 11;
}
For starters pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
The presented two programs actually are equivalent except that in the first program the variable a is changed through a pointer to it.
As it is written in the C Standard (6.2.5 Types, p.#20)
... A pointer type describes an object whose value provides a
reference to an entity of the referenced type.
This property of pointers is used in C to implement the mechanism of passing objects by reference to functions.
Consider the following program.
#include <stdio.h>
void f( int x )
{
x = 10;
}
void g( int *px )
{
*px = 10;
}
int main(void)
{
int x = 0;
printf( "Before calling f x = %d\n", x );
f( x );
printf( "After calling f x = %d\n", x );
x = 0;
printf( "\nBefore calling g x = %d\n", x );
g( &x );
printf( "After calling g x = %d\n", x );
return 0;
}
The program output is
Before calling f x = 0
After calling f x = 0
Before calling g x = 0
After calling g x = 10
As you can see after calling the function f the value of the variable x declared in main was not changed. The problem is that the function deals with a copy of the value of the variable x declared in main. That is the function parameter is a local variable of the function that was initialized by the value of the variable x declared in main. Changing the local variable does not influence on the variable x declared in main.
But when the variable x is passed to the function g by reference through a pointer to it then the function is able to change the original variable x declared in main by means of dereferencing the passed pointer.
Also bear in mind that when you allocate a memory dynamically then allocated objects do not have names. You only have pointers to dynamically allocated objects. For example
int *px = malloc( sizeof( int ) );
So to change the allocated object you also need to dereference the pointer
*px = 10;
In this case nothing, but suppose that you want to call a function, if want to edit the value of a FROM INSIDE that function, you'll need to use pointers.
#include <stdio.h>
void set_a(int *p, int val)
{
*p = val;
}
int main()
{
int a = 2;
printf("a is: %d\n", a); // a is 2
set_a(&a, 5);
printf("a is: %d\n", a); // a is 5
}
that's just one use case. for instance, when using heap allocations, you'll need to use pointers.
The two programs have the same observable effect.
What is the purpose of using pointer to change the value of mutable object?
One good use is to be able to reuse logic. Write it once and use it many times.
Example:
void foo(int *X, int *Y) {
/* some complex calculation */
*X = *X + *Y + 1;
*Y = *Y + *X + 2;
}
Now, you could use the function to do this "complex" calculation on different variables. You only need to write and test it properly once and can then reuse it many times.
int main() {
int a = 10, b = 20, c = 30, d = 40;
foo(&a, &b);
foo(&c, &d);
//...
}
Demo

Comparing two ways of initializing an int pointer

Suppose I have a pointer
int *x;
Then I need to let the pointer point to an int of value, say 42.
Should I do this:
*x = 42;
or this:
int y = 42;
x = &y;
? What is the usual practice?
After this declaration
int *x;
the pointer x either is equal to NULL (if it is declared outside any function) or has an indeterminate value. So dereferencing the pointer like
*x = 42;
invokes undefined behavior.
You can write either
int y = 42;
x = &y;
or
x = malloc( sizeof( int ) );
*x = 42;
When you do:
int *x = 42;
you assigne the pointeur x to the memory case 42, that gonna make a segmentation fault.
The right way to do what you wan't is:
int y = 42;
x = &y;
x gets the adress of y (&y)
#include <stdio.h>
int main()
{
int y=42;
int x=&y;
printf("\nY = %d is at adress X = %d \n",y,x);
}

Pointer as a parameter in C

Let's say a have a pointer as a parameter, why doesn't it's value remain modified after the and of a function, and i have to use this syntax :
void function_name (int **p)
{
// code
}
and in main() :
int *v;
function name (&v);
I want to specify that i use a pointer to a struct type as a parameter.
C passes arguments by value. If you want to modify something in a function and make the modification take effect in the calling function, a pointer to the variable in the calling function has to be passed. Otherwise, any changes made to the variable in a function are only local changes and does not affect the value of the variable in the calling function.
Let's start with an int type variable.
void foo(int x)
{
x = 10;
}
int main()
{
int a = 100;
foo(a); // Value of a does not change in this function
}
In the above program, the value of a remains 100 in main. The line
x = 10;
in foo only affects the value of the variable in foo. To make the change in foo affect the value in main, you'll need to pass a pointer to a.
void foo(int* x)
{
*x = 10;
}
int main()
{
int a = 100;
foo(&a); // Value of a changes in this function
}
Take that analogy to a pointer.
void bar(int* x)
{
x = malloc(10*sizeof(int));
}
int main()
{
int* ptr = NULL;
bar(ptr); // Value of ptr does not change in this function
}
bar allocates memory for an array of 10 ints and assigns the memory to x but that change is local. main does not see it. In main, ptr is still NULL. To make the change in bar affect ptr, a pointer to ptr has to be passed to bar.
void bar(int** x)
{
*x = malloc(10*sizeof(int));
}
int main()
{
int* ptr = NULL;
bar(&ptr); // Value of ptr changes in this function
}
In C, arguments are passed by value. This means that when you pass an argument to a function, a copy of that variable is made. For example
int main()
{
int x = 6;
repchar(x, 'r');
printf("%d\n", x);
return 0;
}
void repchar(int n, char c)
{
while (--n >= 0)
putchar(c);
}
This program prints the letter r six times, and then at the last printf, prints out 6, not -1. The reason is that when repchar was called, x was copied. That way, when repchar decrements n, the caller's copy is not changed.
If we passed a pointer, however, n would be modified.
int main()
{
int x = 6;
repchar(&x, 'r');
printf("%d\n", x);
return 0;
}
void repchar(int *n, char c)
{
while (--(*n) >= 0)
putchar(c);
}
Instead of the variable being copied, now the address of the variable is being copied. Inside of repchar, *n is being counted down. This accesses the value that is being referenced by n, which is the same address as x and decrements it. As a result, the last printf will give -1.

Pointer returning memory address?

I'm working with the program that scans a number in the main program. After that this program calls for a function change_number(), and as an argument gives the numbers memory address. After this program should add 3 to the number in the sub-program, print it out in the subprogram and restore that new value. However, when trying to print the number out in the subprogram change_number(), it prints out it's memory address. My understanding is that a program should return integers value when referring to the pointer with * -notation or just by inserting a variables name. Another compiler which i have tried says the following error message, and does not even compile, either with x -notation or with *pointer_x -notation:
"You are trying to initialize a variable to a value that is of the wrong type.
code.c:20: warning: assignment from incompatible pointer type".
I don't understand because my pointer is introduced as an integer, just like the integer itself. Here is the code:
#include<stdio.h>
void change_number(int *x);
int main()
{
int x;
printf("Give number x: ");
scanf("%d", &x);
printf("In main program: x = %d\n", x);
change_number(&x);
printf("In main program: x = %d\n", x);
return 0;
}
void change_number(int *x)
{
int *pointer_x;
pointer_x = &x;
x = x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
The code you've pasted should fail to compile on the line pointer_x = &x; as both x and pointer_x are type int*
Using the address-of operator on a pointer variable gives you a pointer-to-pointer - in this case, &x yields a type of int**
In addition, the line x = x + 3 advances a pointer location in memory by 3*sizeof(int) bytes, it's not modifying the original int variable.
Perhaps you intended to write *x = *x + 3 instead?
void change_number(int *x)
{
int *pointer_x;
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
The parameter x already contains address of the variable x from main so it have to be written as
void change_number(int *x)
{
int *pointer_x;
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
}
When you write void change_number(int *x), x is received as an int *. So, x points to int and *x is int.
So you'll need to change the following:
pointer_x = x;
*x = *x + 3;
printf("In sub program: x = %d\n", *pointer_x);
Now this prints correctly. But to restore the value, just add this line at the end:
*x = *x - 3;

Resources