10

I am trying to modify the value of local variable through another called function, but I am not able to figure out what all values pushed onto the stack are.

#include <stdio.h>
#include <string.h>

void fun()
{
  int i; 
  int *p=&i; 
  int j; 
  for(j=0;*(p+j)!=10;j++);
  printf("%d",j);
  /* Stack Frame size is j int pointers. */ 
  *(p+j)=20; 
}    

main()
{
  int i=10;
  fun();
  printf("\n %d \n",i);
}

How exactly does j in fun() equal to 12? I am trying to understand what values are pushed onto stack. More specifically, can we change the value of i which is in main() without using a for loop in fun() and is it possible to predict the value of j inside fun()?

Jongware
  • 22,200
  • 8
  • 54
  • 100
debonair
  • 2,505
  • 4
  • 33
  • 73
  • This should address your problem. http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – Richard Czechowski Oct 29 '14 at 03:44
  • 2
    It could be simpler. `void fun(int* ip) { *ip = 20; } int main() { int i = 10; fun(&i); }` – R Sahu Oct 29 '14 at 03:50
  • 2
    @RSahu: The purpose of question is to understand what values are pushed onto stack – debonair Oct 29 '14 at 03:53
  • 1
    @DickTanner That question is at best distantly related to this one. – Jim Balter Oct 29 '14 at 03:59
  • "I am trying to understand what values are pushed onto stack." -- To do that, look at the assembler output, and/or the documentation of your compiler's calling sequence. – Jim Balter Oct 29 '14 at 04:00
  • 3
    a variable doesn't necessarily have to be on stack – phuclv Oct 29 '14 at 04:00
  • @debonair: Looking around the web for information on the call stack and calling convention might help – Uchia Itachi Oct 29 '14 at 04:01
  • Maybe you're running into a different `10`. Try a different number like `12345`. – ooga Oct 29 '14 at 04:03
  • @ooga Not if the OP's program prints 20. Too bad the OP didn't say. – Jim Balter Oct 29 '14 at 04:04
  • @LưuVĩnhPhúc Yes, this question is based on several misconceptions about the C language and what one can expect of non-conforming programs. – Jim Balter Oct 29 '14 at 04:06
  • 1
    @JimBalter Good point! When I ran it it still printed `10`. Changing the original number to `12345` resulted in the expected `20` for `i` in `main` and `14` for `j` in `fun`. – ooga Oct 29 '14 at 04:07
  • @ooga You changed it to `i=12345` and it printed `i` as 20? That would be strange. – Jim Balter Oct 29 '14 at 04:09
  • @JimBalter Yes I also tried to print i in main and it prints 20. The value of j is undefined as if we add one more variable in main() before calling fun() the value of j changes – Gopi Oct 29 '14 at 04:11
  • 1
    @Gopi You got 20 but I doubt that you changed `i=10` to `i=12345`. "The value of j is undefined" -- the whole program has undefined behavior, so yes of course the C standard does not define what `j`s value will be. "if we add one more variable in main() before calling fun() the value of j changes" -- well of course; that's the whole point of the OP's exercise. – Jim Balter Oct 29 '14 at 04:15
  • @JimBalter How would that be strange? `fun` scanned the stack until it found the value `12345` and then changed it to `20`. – ooga Oct 29 '14 at 05:06
  • first the parameters are pushed on the stack, in reverse order, by the caller: then the PC is pushed on the stack, by the hardware; then local variables of the called function are pushed on the stack, in reverse order, by the called function. – user3629249 Oct 29 '14 at 16:54
  • @ooga It's not strange if you changed it to `i=12345` **and** you changed it to `for(j=0;*(p+j)!=12345;j++);`, but that wasn't clear. – Jim Balter Oct 29 '14 at 22:24
  • @user3629249 Not necessarily. – Jim Balter Oct 29 '14 at 22:42

2 Answers2

3

When you have to access local variables from other function calls, I think you had better redesign your code.

Theoretically, you can direct to modify the i of main() in fun() if you can completely understand how the compilers deal with the activation records of function calls on the run-time stack. You can read "Compilers: Principles, Techniques, and Tools" for details( http://www.amazon.com/Compilers-Principles-Techniques-Tools-Edition/dp/0321486811 )

enter image description here

The value of j depends on the run-time stack address between the int i; in the fun() and int i = 10; in main() . In this case, when fun() is called, their relative distance on stack is just 12. That is why the j is 12. So the *(p + j) = 20; actually changed the i of the main(). If you change your code by adding int a = 14; as following, you will find the value of j changed for the activation record on the run-time stack has been changed.

#include <stdio.h>

void fun()
{
  int i;
  int *p=&i;
  int j;
  for(j=0;*(p+j)!=10;j++);
  printf("%d",j);
  /* Stack Frame size is j int pointers. */
  *(p+j)=20;
}

main()
{
  int i=10;
  int a=14;  /* add this for example to change the relative address i in the main and i in the fun*/
  fun();
  printf("\n %d \n",i);
}
Yulong Ao
  • 1,199
  • 1
  • 14
  • 22
  • "in the fun i will be initialized by 0 if you don not explicitly assign something to it" -- no it won't. The value is undefined and in most implementations will be whatever junk is in the stack location or register used to hold `i`. if it happens to be 10, then j will be 0. The rest of what you wrote is too convoluted for me to parse. – Jim Balter Oct 29 '14 at 22:30
  • @JimBalter: Yes, you are right. I'll try my best to express my idea well and I have edited the answer. – Yulong Ao Oct 30 '14 at 02:39
0

Here in fun()

  • i contains 0 or some garbage value
  • p contains the addresses of i

In the for loop j is initially 0 and the for loop will run until the value in the address p+j !=10 and j is incremented.

So there is no way to correctly predict the outcome of the print in fun()

and also before getting out of the fun() you are trying to assign 20 to the memory location p=j where j could be any value [0,+infinity) no way of telling correctly

meanwhile the print func in main() will display value of local i that is 10 that is if the address of this i in main() in not equal to p+j

Hamad
  • 5,096
  • 13
  • 37
  • 65
AVIK DUTTA
  • 736
  • 6
  • 23
  • 1
    You're missing the whole point of the OP's code. It assigns a stack address to `p`, then searches the stack until it finds the value `10`, which presumably gives the offset between local variable `i` in fun and local variable `i` in main ... assuming that both of these variables are on the stack, there is no other instance of `10` on the stack inbetween, and that the stack grows downward. – Jim Balter Oct 29 '14 at 22:34