Как только вы выйдете функцию f()
, переменная j
выходит из области видимости, пока указатель p
является все еще указывает на этот адрес памяти. Это неопределенное поведение.
Упрощенная рядный версия кода, прокомментировал, что происходит:
int main()
{
int *p; //create pointer
{
int j = 11; //create j in local scope
p = &j; //set p to point at j (refered to as address A from now)
printf("%d ", *p);//print value at A "11 "
} //j goes out of scope
printf("%d ", *p); /*print value at A "11 11 "
***UB: as memory at A is not used to store j any more,
printf() can use it to store variables for its own use*/
printf("%d ", *p); /*print value at A "11 11 GARBAGE"
***UB: as memory at A is not used to store j any more,
the previous printf() call touched A at some point
changing the contents (and thus the read value)*/
}
Честно говоря, я удивлён, что призыв к первому printf()
не затирать память перед выводом его.
Вы не можете полагаться на второй printf
, выводящий «правильное значение». Даже в этом простом примере поведение, видимое, продиктовано только реализацией, и другой компилятор, скорее всего, справится с этим по-разному.
Просто изменив код, очень, вероятно, что выход изменится, например, объявив новую переменную до того, как printf
, скорее всего, перепишет память и остановит вывод из правильного.
На какой нечестивой системе '% d' print' "неопределенное значение" '?? –
@ TheParamagneticCroissant: ну, в конце концов, это неопределенное поведение. :) –
@ DanielKamilKozar Точно ...: P –