Pointers not giving expected result - c

I am a beginner. I was working around with pointer when I found something strange:
#include<stdio.h>
int* fun(int*);
int main()
{
int i=4,*j;
j=fun(&i);
printf("%d ",*j);//gives correct answer -> how??
printf("%d",*j);//gives incorrect answer
}
int* fun(int *i)
{
int k;
k=*i;
return (&k);
}
In main(), I am usingprintf("%d ",*j);` 2 times. First one is giving me right answer, but second one is not. Why?
but this is working fine-
‎#include
int *func();
int main()
{
int *p;
p=func();
printf("%u", p);
printf("\n%d", *p);
printf("\n%d", *p);
printf("\n%d", *p);
printf("\n%d", *p);
}
int* func()
{
int i=10;
printf("%u", &i);
printf("\n%d", i);
return (&i);
}

You are invoking undefined behavior by returning a pointer to a local variable. After the function fun returns, the space occupied by the local variable k is not valid anymore. Actually the space on the stack previously used by fun is probably overwritten by the first call to printf.

You're returning the address of a variable that's local to fun; once fun exits, that variable no longer exists, and the pointer is no longer valid. Strictly speaking, the behavior is undefined.
What's most likely happening is that the memory location that k used to occupy gets overwritten after the first call to printf.

Related

why does a pointer to pointer points on a printf output without making any changes with the pointer

I found this question, I should tell what will be the output.
#include <stdio.h>
int main()
{
int i = 10;
int *p = &i;
foo(&p);
printf("%d ", *p);
printf("%d ", *p);
}
void foo(int **const p)
{
int j = 11;
*p = &j;
printf("%d ", **p);
}
I think it shuold be 11 11 11. The answer is 11 11 unefined.
I checked with debugger and I found that the printf returns 3, and after the second print p point to that value 3. I don't know why it happens.
If someone can explain that would be great.
thanks.
That happens because you're assigning p to the address of a local variable, so the behavior is actually undefined both for the second and the third printf.
Once the function reaches the end, all its local variables fall out of scope. The memory they used is no longer reserved, so p points to an address which may still contain the value 11, but it may have been overwritten as well, as is the case on your computer (on mine I get 11 every time, but it's only a fortuity).
To make sure the value isn't lost, you could declare j as a static or global variable or allocate it with an *alloc function.

Why does global pointers behave erratically in this function?

I've tried to write a program that uses global pointers to track down local variables, but when I use the right syntaxes, it doesn't run.
When I alter the syntaxes, the program yields correct results. I don't fully understand the mechanism behind it, and hoping that more experienced coders could explain it. Thank you.
#include <stdio.h>
#include <math.h>
int *q;
int *u;
int *p;
void test () {
printf("Insert #1?\t"); scanf("%d", &u);
/*should be scanf("%d", u) for u is a pointer*/
printf("Insert #2?\t"); scanf("%d", &p);
/*should be scanf("%d", p) for p is a pointer*/
}
int main () {
test ();
printf("%d\n", u);
/*should be printf("%d\n", *u) since I am trying to dereference the value of u*/
printf("%d\n", p);
printf("%d\n", q);
}
The output should be 3 numbers, 2 first numbers are inputs from user, and the third one should be a nonsense number since the 3rd pointer is not pointing anywhere.
Update: It works!!!!! Thank you so much for your help :).
This has nothing to do with global variables. There are multiple problems here but the most pressing error is that you are attempting to use uninitialised pointers. This never works. You need to understand pointers before you can use them properly.
In particular, if you have a declaration like this:
int *x;
Then, no matter what you do, you first need to assign a valid pointer to x1.
In your case the error is compounded by the fact that you’re using scanf wrong. Luckily the solution here is very easy: Don’t declare pointers. Instead, declare int variables.
#include <stdio.h>
int q;
int u;
int p;
void test () {
printf("Insert #1?\t"); scanf("%d", &u);
printf("Insert #2?\t"); scanf("%d", &p);
}
int main () {
test();
printf("%d\n", u);
printf("%d\n", p);
printf("%d\n", q);
}
Ironically the comments in your original code already point out the issue, they just suggest a wrong solution. It’s a bit of a mystery where these comments are from. ;-)
1 Technically the only exception is for statically allocated pointers, which are correctly zero-initialised and can therefore be used in null pointer comparisons.
Your global variables are the pointers to the ints, not the ints themselves. When you read in the values, you change where in memory u points to, not the value of u.
You should replace it with either scanf("%d", u); or change the declaration to int u.
You need to be careful taking pointer values from the user. Otherwise, you could risk things like null pointer dereferencing. For instance, Entering 0 when you scanf("%d", &u);, it would then make the value of u be NULL.
As I said in my comment to the question, a pointer is a type that holds the address to another variable of some type, so int* holds an address for a variable of type int. In your case, &u is referring to the address of u, so you're trying to scan a number into a pointer which won't work. You should change it to only u so it will scan to the variable it points too, but it needs to point to a valid variable in the first place. Here is a valid example:
int someNumber = 5;
int* u = &someNumber; // u points to a valid address statically allocated
scanf("%d", u); // Scans the number inputed to someNumber because u points to it
getchar(); // Avoid buffer overflow
printf("%d\n", *u); // A * dereferences u - gets the value of the variable it's pointing to
Pointers need to point to something, such as another variable, or memory allocated dynamically with malloc().
You can't use scanf() to read directly into a pointer. You can use it to read into what the pointer points to.
So you can write something like this:
#include <stdio.h>
#include <math.h>
int q;
int *qp = &q;
int *up;
int p;
int *pp = &p;
void test () {
printf("Insert #1?\t"); scanf("%d", up);
printf("Insert #2?\t"); scanf("%d", pp);
}
int main () {
up = malloc(sizeof(*up));
test ();
printf("%d\n", *up);
printf("%d\n", p);
printf("%d\n", q);
}
Your pointers have no value assigned to them.

Shifting pointer to some address by calling another function

Why in this code the pointer shifts to another location:
#include <stdio.h>
void f(int *p)
{
int j=2;
p=&j;
printf("%d\n%p\n%d\n",*p,&j,p);
}
int main(void)
{
int *q;
int m=98;
q=&m;
f(q);
printf("%p ",q);
return 0;
}
Output:
2
0x7ffff5bf1bcc
0x7ffff5bf1bcc
0x7ffff5bf1bc8
I understand that when the function f() is done with printing value of j and address of j the memory occupied by j goes back to the stack but IMO p should continue pointing that location even after the function is over & it should be printing the same address in main as well. What is wrong with this?
Considering you meant printf("%p ", (void *)q); in the actual code,
No, function argument(s) in C is (are) passed by value. It won't reflect the changes made to the parameter into the actual arguments used (in function call) themselves.
To put it into other words, the function parameters are local to the function (call) scope, any changes made to them won't be reflected to the actual arguments.
So, if you need to change a pointer, you need to pass a pointer to the pointer which needs to be changed.
Consider a rather light-hearted but realistic scenario.
void f (int x) { x = 10; }
int main(void) { f(5); printf ("%d", 5); return 0;}
Now, do you expect it to print 10?
That said, an advice. Always cast the argument to %p conversion specifier to (void *) (if it is not already). printf() is a variadic function and for pointers, no default argument promotion happens, so the supplied argument type needs to match the expected type, explicitly. Otherwise, technically it is undefined behavior.
Learn the difference between Pointers and Pointers to pointers - the pointer passed p is no doubt good to change the value of the variable it is pointing to (m), but to change the memory location it is pointing to - you need a pointer to pointer.
Expanding on top of what #SouravGhosh said, when you pass in a pointer to an int you are making a copy of the pointer. If you wanted to change the pointer you need to be doubly indirect and pass in a pointer to a pointer to an int. The first pointer is copied and you can directly affect the second pointer.
void f(int ** p)
{
int j = 2;
*p = &j;
printf("%d\n%p\n%p\n",*p,&j,p);
}
int main(void)
{
int ** q = (int **)malloc( izeof(int *));
int m = 98;
*q = &m;
f(q);
printf("%p ",q);
free(q);
return 0;
}
And the output is
2
0xffffcbcc
0xffffcbcc
0xffffcbcc
If you do this you'll see that it never changes:
#include <iostream>
#include "Header2.h"
#include "header1.h"
#include <stdio.h>
void f(int *p)
{
int j = 2;
p = &j;
printf("%d\n%p\n%p\n", *p, &j, p);
}
int main(void)
{
int *q;
int m = 98;
q = &m;
printf("Value of pointer q before calling f() =%p ", q);
f(q);
printf("Value of pointer q after calling f() =%p ", q);
return 0;
}

Why Third printf will print undefined value?

#include <stdio.h>
int main()
{
int i = 10;
int *p = &i;
foo(&p);
printf("%d ", *p);
printf("%d ", *p);
}
void foo(int **const p)
{
int j = 11;
*p = &j;
printf("%d ", **p);
}
What wii be the final output
Why Third printf will print undefined value ?
Within foo, you assign a value to *p which points to a location on the stack that's been allocated to foo. When foo returns, the stack is popped, and that location is free for reuse — but the p in main still points to it.
When you call printf in main the first time, it happens that that that location on the stack hasn't (yet) had any new data written to it, and so reading *p gives you 11, and you push that on the stack along with some other things for the call to printf, and it succeeds in printing 11. But the action of calling printf changes the data on the stack, including (potentially) the location that p (in main) points to, because the stack was popped after foo returned.
The second call then uses the data from that stack location again, which may have been changed by the first call to printf.
Moral of the story: Don't keep pointers to stack locations that have been popped.
the "i" in foo is stack-allocated, every thing will work fine until it goes off from the memory, so printf of foo will work fine,while the second printf and the third printf will work until the integer i of foo goes off from the memory. This is a system issue, it has the probability that the 2 last printf's work or don't work. If you wanna them work all the time you need to heap-allocate integer i of foo using mallo
Third printf is printing the right value. The problem is that j is an automatic local variable and it is no longer exist once function return. Therefore, p in main is not pointing to the place you are expecting and ultimately your program invokes undefined behaviour.
Possible solutions:
1. Use static keyword in the declaration of j
void foo(int **const p)
{
static int j = 11;
*p = &j;
printf("%d ", **p);
}
2. Dynamically allocate j
void foo(int **const p)
{
int *j = malloc(sizeof(int));
*j = 11;
*p = j;
printf("%d ", **p);
}
When void foo() is called ,new stack frame gets created on stack so int j = 11; being a local variable goes into this stack frame . So say int j is at address 0x000ffd with value 10 so your *p now stores this address . Now what happens when this function returns stack unwinds
During Stack Unwinding , it does all the work of cleanup. so all data which is into that stack frame gets destroyed so now that address 0x000ffd might have same value or something different but variable j is not associated to it now. So its undefined behavior

Functions and pointer to pointers

I have been trying to create a pointer variable in the called function and somehow pass the value pointed by it to the main function. I wrote a few sample programs but it i still seem to be missing something out. and the challenge was to achieve this using pointers to pointers to pointers. Here is the code that I wrote and tested. I think am missing something obvious, can you guys point it. Thanks.
int one(int ***ptr)
{
static int *p,**pp,b=10;
p=&b;
pp=&p;
ptr=&pp;
printf("b:%d\tp:%d\tpp:%d\n",b,*p,**pp);
printf("Sub Ptr:%d\n",***ptr);
printf("Address of ***ptr:%d\n",&ptr);
return 32;
}
int main(int argc, char *argv[])
{
static int ***ptr;
int a=200,*b,**c;
b=&a;
c=&b;
ptr=&c;
printf("Main Ptr:%d\n",&ptr);
a=one(ptr);
printf("Main Ptr:%d\n",&ptr);
printf("Main Ptr:%d\n",***ptr);
system("PAUSE");
return 0;
}
I get an output of 32 which is the return value of the function. Is it possible to get the value of 10 which is pointed in the called function.
I also tried global declaration but din work either. I would like to maintain the local declaration and see if its possible...
I think you misunderstood about pointers. The problem of your code is that you didn't realize that pointer is also "pass by value", the pointer in the function is another variable on the stack, instead of the one you declare in the main function.
I would use a more simple example, but the idea is the same.
void changePointerValue (int * ptr)
{
int newValue = 10;
ptr = &newValue;
}
int main ()
{
int x = 20;
int * ptr = &x;
changePointerValue (ptr);
printf ("After Change: %d\n", *ptr);
}
What value do you think it will output in main function? Is that be 10?
But no, in fact, it will output 20.
Why? Let's look what our code does. In the line of chagePointerValue(ptr), the computer copy the value of ptr in the main function to a new varaible on stack, let's call it ptr' and pass it to the changePointerValue function.
So in fact the ptr in the changePointerValue function is ptr', not the one you declare in the main function. The second line of changePointerValue, you assigned a new memory address to ptr', and after that, ptr' is discarded because the function is returned. The ptr in the main function remains the same value, which is the memory address pointed to x.
If you want the output to be 10, you need deference ptr in the changePointerValue, and the assignement will means 'Change the value where the ptr is pointed at'.
void changePointerValue (int * ptr)
{
int newValue = 10;
*ptr = newValue; // Now you are change the content of the memroy cell where ptr is pointed at.
}
int main ()
{
int x = 20;
int * ptr = &a;
printf ("Before Change:%d", x); // 20
printf ("Before Change:%d", *ptr); // 20
changePointerValue (ptr);
printf ("After Change: %d\n", *ptr); // 10
printf ("After Change: %d\n", x); //10
}
Edit:
So, if you want it print 10 in the main function, the correct way to do this is deference ptr in the function. But this will also change the value of variable a in the main function.
int one(int ***ptr)
{
***ptr=10; // Dereference ptr to where it points to. (Varaible a in the main function)
return 32;
}
int main(int argc, char *argv[])
{
static int ***ptr;
int a=200,*b,**c;
int result;
b=&a;
c=&b;
ptr=&c;
printf("Main Ptr:%d\n",&ptr); // The memory address of variable ptr.
result=one(ptr);
printf("Main Ptr:%d\n",&ptr); // the memory address of variable ptr.
printf("Main Ptr:%d\n",***ptr); // 10
printf("Main a:%d\n", a); // 10
printf("Main result:%d\n", result); //32
system("PAUSE");
return 0;
}
You're setting ptr to the address-of-the-address-of-the-address-of a local variable (b), which goes out of scope at the end of the function. This is undefined behaviour. You either need to assign to ***ptr, or malloc something on the heap.
Also, you're passing ptr by value to the function. So any local modifications to it won't be reflected in main. You need to pass by pointer, i.e. you'll need an int **** as an argument.
I really hope this is nothing more than a learning exercise, because any more than two levels of pointers usually indicates that the design really needs to be re-evaluated!

Resources