озадачен выводом

почему printf печатает 7, хотя переменная a была локальной для функции fun() и больше не должна существовать после возврата элемента управления из функции fun().

Вот код с

‎#include<stdio.h>

main()
{
    int *fun();
    int *c=fun();
    printf("%d",*c);
    getch();
}

int *fun()
{
    int a=7;
    return(&a);
}

выход : 7


person user1474089    schedule 22.06.2012    source источник
comment
возможный дубликат возврата локальной переменной из функции в C   -  person Bo Persson    schedule 22.06.2012


Ответы (4)


Это связано с тем, что даже если переменной больше не существует, область памяти, в которой она находилась, еще не использовалась для чего-то другого. Следовательно, указатель по-прежнему указывает на ячейку памяти, где биты содержат int со значением 7.

Но это определенно неопределенное поведение. Вы не должны полагаться на него.

person Didier Trosset    schedule 22.06.2012

Существует разница между языковыми идиомами и физической работой оборудования. В словах "C" да, ваша переменная больше не должна быть доступна, но физически переменная a была выделена в стеке вашей программы, которая не стирается каждый раз, когда функция возвращается (это заняло бы слишком много времени), таким образом вы все еще можете прочитать это.

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

person strnk    schedule 22.06.2012
comment
но почему этот код всегда печатает мусор? #include‹stdio.h› main() { char *s; символ *весело(); с=весело(); printf(\nпривет..1\n); printf(%s,s); получить(); } char *fun() { char str[30]; strcpy(str,это слишком просто\0); возврат (стр); } - person user1474089; 22.06.2012
comment
Потому что вы больше ничего не делаете между вызовом функции (инициализация стека и возврат указателя на переменную в стеке) и printf значения, на которое указывает эта переменная. Скорее всего, если вы вызовете другие функции, вы прочтете что-то еще. РЕДАКТИРОВАТЬ: например, ваш код печатает строку мусора в моей системе. - person strnk; 22.06.2012

после возврата fun() указатель фрейма снова устанавливается на фрейм main(). указатель c указывал на какой-то адрес в памяти, так как функция fun() уже вернулась, мы не знаем, что в адресе, но если в адрес больше ничего не было записано, то это может быть и предыдущая переменная a. стандарт C просто перемещает указатель кадра, когда функция возвращается.

person nzomkxia    schedule 22.06.2012

Я думаю, это потому, что вы печатаете *c , который отображает значение, которое хранится в местоположении, т.е. &a , просто попробуйте напечатать c , тогда вы получите адрес 7 .

Это связано с тем, что адрес уже передан в переменную c, а адрес памяти может быть прочитан и вне функции.

person TRonZ    schedule 22.06.2012
comment
Но нам не разрешено читать этот адрес памяти вне функции. - person Bo Persson; 22.06.2012
comment
@BoPersson Но значение адреса памяти уже передано в другую переменную, т.е. c . - person TRonZ; 23.06.2012
comment
Но поскольку a больше нет, чтение из *c также не разрешено. Это неопределенное поведение, и может произойти все что угодно, включая printf вывод 7 (или 42, или сбой). - person Bo Persson; 23.06.2012
comment
@BoPersson a там нет, но он тоже не удаляется полностью, значение a сохраняется в памяти до тех пор, пока мы сами его не удалим. - person TRonZ; 23.06.2012