C pointer to a pointer confusion - c

I have the following code. I tried to change the value of y by using a pointer to a pointer (i.e. trying to do a de-referencing twice from the pointer that points to another pointer). this is my code, but for some reasons it doesn't work, could someone tells me where I have done wrong:
#include <stdio.h>
void changeAddr(int **j) {
(*j)++;
printf("change pointer's address to: %p\n", j);
(**j)++; // is there something wrong with this part? I want to increase the
// value pointed to by the pointer pointed to by j (so I thought
// it would be the value of y in main, but there is an error message
// the error says: *** stack smashing detected ***: terminated
printf("change the value pointed to by the pointer by using a pointer: %0d\n", **j); // this does not
// give value 7 for some reasons
}
void inval(int *i) {
(*i)++;
printf("address of i: %p\n", i);
printf("just increased: %0d \n", *i);
changeAddr(&i);
}
int main()
{
printf("Hello World\n");
int y = 5;
inval(&y);
//printf("%0d\n", y);
printf("%p\n", &y);
printf("value of y in the end: %d\n", y);
return 0;
}

int y = 5;
inval(&y);
/* inside intval(int *i): i points to a single int */
(*i)++; // Increments y
changeAddr(&i);
/* inside changeaddr(int **j): j points to a pointer to a single int */
(*j)++; // Increments i; i now points to the next thing after y;
// the spec says we can always do this but dereferencing it is undefined
(**j)++; // Increments the next thing after y; oops that's undefined behavior */

Related

is there a way we can make functions that return pointers in C?

I mean, can we make functions return pointer like in this code:
#include <stdio.h>
int* sum(int* ptr_1, int* ptr_2){
return (*ptr_1 + *ptr_2);
}
int main() {
int x=0, y=0;
scanf("%d %d", &x, &y);
int *ptr_x = &x;
int* ptr_y = &y;
printf("%d", *sum(ptr_x, ptr_y));
return 0;
}
This code takes 2 int numbers and prints sum of them using pointers. It didn't work on ssh but I wanted to ask anyway.
That code is buggy. It returns the sum of two ints as a pointer which doesn't make sense.
You can return pointers, but they should also point at something (or NULL). Dereferencing the pointer returned by sum (as you do in the printf line) will almost certainly cause undefined behavior.
A contrived but working version of your program:
#include <stdio.h>
int *sum(int *ptr_1, int *ptr_2) {
// `static` makes `result` stored between calls so it isn't destroyed
// when the function returns:
static int result;
result = *ptr_1 + *ptr_2;
return &result; // return a pointer pointing at result
}
int main() {
int x, y;
if(scanf("%d %d", &x, &y) != 2) return 1;
int *ptr_x = &x;
int *ptr_y = &y;
printf("%d", *sum(ptr_x, ptr_y));
}
Yes, functions can return pointers.
Your problem is that the expression *ptr_1 + *ptr_2 yields a value of type int, not int * (each of *ptr_1 and *ptr_2 are ints, so adding them together gives you an int value).
Whatever that integer value is, it's likely not a valid pointer (it's not the address of an object during that object's lifetime), and the behavior on dereferencing an invalid pointer is undefined. Your code may crash, you may get nonsensical output, something else may happen.
Yes, you can return a pointer, but in this specific case, you do not need to, your sum should simply return an int, not a pointer to int:
int sum(int* ptr_1, int* ptr_2){
return (*ptr_1 + *ptr_2);
}

Reading a pointer

I have a vector
int a[100].
I have read the vector and gave it the values 1,2,3.
Now i want to use a pointer
int *pa=&a[100].
My question is can I read the pointer via scanf and give the vector a[100] some new values?
i have tried doing this:
for(i=0;i<n;i++)
{
scanf("%d",&a[i])
}
for the vector and for the pointer:
for(i=0;i<n;i++)
{
scanf("%d",&pa)
}
This is my main:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a [100],n,i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<n;i++)
{
printf("%d",a[i]);
}
for(i=0;i<n;i++)
{
scanf("%d",&pa);
}
for(i=0;i<n;i++)
{
printf("%d",pa);
}
return 0;
}
printf("%d",pa) is giving me 999 and the vector a still has the values 1,2,3.
The following code illustrates that pa points to an object and that *pa designates the object.
#include <stdio.h>
int main(void)
{
// Set size of array.
static const int N = 100;
// Define array.
int a[N];
// Initialize array.
for (int i = 0; i < N; ++i)
a[i] = i+1;
// Define a pointer and initialize it to point to element a[0].
int *pa = &a[0];
/* Scan as if "34" were in the input. Observe that we pass pa, not &pa.
&pa is the address of pa. pa is the value of pa. Its value is the
address of a[0].
*/
sscanf("34", "%d", pa);
// Print a[0]. This will be "34".
printf("%d\n", a[0]);
/* Print *pa. Note that we use *pa, which is the object pa points to.
That objects is a[0], so the result is "34".
*/
printf("%d\n", *pa);
/* Change pa to point to a different element. Note that we use "pa =
address" to set the value. This is different from the initialization,
which had "int *pa = value". That is because declarations need the
asterisk to describe the type, but an assignment just needs the name;
it does not need the asterisk.
*/
pa= &a[4];
// Print *pa. Since pa now points to a[4], this will print "5".
printf("%d\n", *pa);
}

Printing what is stored in pointer prints what is stored in that memory adress

When I try to print this
#include <stdio.h>
int main(){
int x = 3;
int *ptr = &x;
//printf("Address is : %d\n",&ptr);
ptr++;
*ptr = 1;
printf("%d %d",x,ptr);
return 0;
}
The code outputs 3 1, shouldn't it be 3 (then address of ptr?). Then, when I uncomment first printf it prints out:
Address is : 6356744
3 6356752
Does anyone know what is going on?
You have several serious problems in your code.
1) You print a pointer value or an address of a variable using %d but should not. That is undefined behavior so we can't know what will happen. To print a pointer value or an address of a variable use %p and cast to a void pointer like:
printf("Address is : %p\n",(void*)&ptr);
2) You write to memory that is not allocated to your program. These lines:
ptr++;
*ptr = 1;
make you write the value "1" one step past x. So this is also undefined behavior.
Correction the above could give you this program:
#include <stdio.h>
int main(){
int x = 3;
int *ptr = &x;
printf("Address is : %p\n",(void*)&ptr);
ptr++;
// *ptr = 1;
printf("%d %p\n",x,(void*)ptr);
return 0;
}
With the possible output:
Address is : 0x7ffc5b0923c8
3 0x7ffc5b0923c8
but the output may change from run-to-run and system-to-system

Passing pointer to function value not changing [duplicate]

This question already has answers here:
Changing address contained by pointer using function
(5 answers)
Closed 4 years ago.
#include<stdio.h>
void foo(int*);
int main()
{
int i = 97, *p = &i;
foo(p);
printf("%d ", *p);
getch();
}
void foo(int *p)
{
int j = 2;
p = &j;
printf("%d ", *p);
}
Output is 2 97
Why not 2 2 ?
pointer p holds the address of j now so why 97 is printed ?
You can imagine the function call and its definition the following way. For clarity I'll rename the function parameter as q.
foo(p);
void foo( /*int *q*/ )
{
int *q = p;
int j = 2;
q = &j;
printf("%d ", *q);
}
As it is seen the function parameter (in this case q) is a local variable of the function that is initialized by the value of an argument (in this case by the value of the argument p)
So any changes of the local variable (q) do not influence on the original argument (p).
After exiting the function the local variable will not be alive.
If you want to change the argument itself you should pass it by reference. For example
void foo( int **p )
{
int j = 2;
*p = &j;
printf("%d ", **p);
}
However after exiting the function the original argument/variable p will be invalid because it stores the address of a non-alive local variable of the function j.
So an attempt to access the memory that was occupied by the function's local variable j results in undefined behavior of the program.
You could make the program correct by declaring the local variable j as having static storage duration. For example
void foo( int **p )
{
static int j = 2;
*p = &j;
printf("%d ", **p);
}
and call the function like
foo(&p);
In foo, you assign a new value to p. However this is a copy of the value of p in main, so the change is not visible in main.
If you dereferenced p, then it would change the value if i in main:
void foo(int *p)
{
*p = 2;
printf("%d ", *p);
}
p = &j;
just changes the value of the local variable p. This has no effect on the caller's p variable (because p was passed by value) or the variable that p previously pointed to (because you didn't indirect through it). If you want to change the caller's data, write:
*p = j;
Go through the above code line by line. Here I have written comments as control passes through each of the lines...
#include<stdio.h>
void foo(int*);
int main()
{
int i = 97, *p = &i; //Lets assume i has address 2000
foo(p); //p contains 2000 which is passed to foo. go to foo at 1.
printf("%d ", *p); // when control comes back no change to p it
//still points to 2000 which stores 97
getch();
}
void foo(int *p) 1: // in foo another local variable p is created.
//Let's call this lp. lp has now address 2000. i.e lp
//and p both point to i but one locally exists in a
// function and will be destroyed when control comes out
// of the function
{
int j = 2;
p = &j; // now local p i.e lp points to another var j
// address. Suppose lp has address 3000 now.
printf("%d ", *p); //val at address in lp is 2
}

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