#c #gcc
#c #ссагпз
Вопрос:
Я просто попробовал это в качестве эксперимента, чтобы посмотреть, какие значения сохраняются d
при каждом вызове. Я использовал gcc
на машине x86-64.
Есть ли какая-либо причина, по которой старое значение d сохраняется после возврата функции? Из того, что я понимаю, фрейм стека вызовов отключается, как только функция возвращается каждый раз, правильно?
#include<stdio.h>
void fun(char ch){
char d;
printf("-- %cn", d);
d = ch;
}
int main(){
fun('a');
fun('b');
fun('c');
return 0;
}
ВЫХОДНОЙ СИГНАЛ:
--
-- a
-- b
Комментарии:
1. Учитывая, что это не определено, есть ли причина, по которой этого не должно быть? Стековый фрейм отключается, но ничто не «очищает» предыдущее значение.
2. Вы только что открыли для себя некромантию стека. Теперь не используй его. Люди будут недовольны его отладкой.
Ответ №1:
Когда вы возвращаетесь из функции, память, которая была частью стекового фрейма функции, обычно не будет обнуляться явно, так как это просто заняло бы ненужные циклы. Таким образом, память не будет перезаписана до тех пор, пока это не потребуется.
В вашей main
функции вы вызываете fun
несколько раз без каких-либо других операторов между ними. Это означает, что ничто в main
не затрагивает память, которая использовалась предыдущим вызовом fun
перед повторным вызовом. В результате кадр стека второго вызова случайно совпадает с кадром стека первого вызова. А поскольку неинициализированные локальные переменные не получают значения по умолчанию, d
они принимают любое значение, находящееся в этой ячейке памяти, а именно то, что d
содержалось при возврате последнего вызова функции.
Если вы добавили вызов другой функции, например, printf
между каждым вызовом to fun
, то этот другой вызов функции записал бы свой собственный фрейм стека поверх фрейма стека последнего вызова to fun
, поэтому в этом случае вы увидите другие результаты.