Какие значения вставляются в стек во время вызова функции?

Я пытаюсь изменить значение локальной переменной через другую вызванную функцию, но я не могу понять, что все значения, вложенные в стек, являются.

#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);
}

Как точно j в fun() равно 12? Я пытаюсь понять, какие значения вставляются в стек. В частности, можем ли мы изменить значение i, которое находится в main(), не используя цикл for в fun() и можно ли предсказать значение j внутри fun()?

Ответ 1

Когда вам нужно получить доступ к локальным переменным из других вызовов функций, я думаю, вам лучше перепроектировать ваш код.

Теоретически вы можете направить изменение i в main() в fun(), если вы можете полностью понять, как компиляторы справляются с активационными записями вызовов функций в стеке выполнения. Вы можете прочитать "Компиляторы: принципы, методы и инструменты" для деталей (http://www.amazon.com/Compilers-Principles-Techniques-Tools- Издание /dp/ 0321486811)

enter image description here

Значение j зависит от адреса стека времени выполнения между int i; в fun() и int i = 10; в main(). В этом случае, когда вызывается fun(), их относительное расстояние в стеке равно 12. Вот почему j равно 12. Таким образом, *(p + j) = 20; фактически изменил i для main(). Если вы измените свой код, добавив int a = 14;, как показано ниже, вы увидите, что значение j, измененное для записи активации в стеке выполнения, было изменено.

#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);
}

Ответ 2

Здесь в fun()

  • я содержит 0 или некоторое количество мусора
  • p содержит адреса i

В цикле for j первоначально находится 0, и цикл for будет работать до тех пор, пока значение в адресе p+j !=10 и j не будет увеличено.

Таким образом, нет возможности правильно предсказать результат печати в fun()

а также перед тем, как выйти из fun(), вы пытаетесь назначить 20 в ячейку памяти p=j, где j может быть любым value [0,+infinity) не указывать правильно

Между тем функция print в main() отобразит значение локального i, которое равно 10, если адрес этого я в main() не равен to p+j