Вы не присвоили p
значение, поэтому оно остается неинициализированным. Попытка разыменовать этот указатель вызывает undefined behavior.
Дайте p
значение, и вы получите результат, который вы ожидаете:
int *p = &x;
Тот факт, что ваш код по-прежнему печати правильное значение является частью этого неопределенного поведения. Один из способов неопределенного поведения может проявиться в том, что код работает правильно, но тогда, казалось бы, несвязанное изменение приведет к его разрыву.
В этой конкретной ситуации функции first
и second
определяют две локальные переменные того же типа и в том же порядке. По завершении вызова first
память, содержащая значения x
и p
от этой функции, все еще содержит эти значения, но еще не было никаких других вызовов функций, чтобы их перезаписать.
После этого звоните second
сразу после first
. Переменные x
и ptr
в second
в конечном итоге используют ту же память, что и x
, и p
в first
. И поскольку ptr
неинициализирован, он по-прежнему содержит старое значение, которое является адресом x
в первую очередь, которое, как оказалось, совпадает с адресом x
в second
.
Опять же, это неопределенное поведение, поэтому вы не можете постоянно зависеть от этого. Если вы добавили другую переменную в first
или вызвали другую функцию между first
и second
, которая изменит память стека, ранее использовавшуюся first
. Затем память будет содержать другое значение, и вы, вероятно, либо распечатаете значение мусора, либо дамп ядра.
Тот же код может давать разные результаты, если скомпилирован с другим компилятором или различными параметрами компилятора. Например, другой компилятор может выбрать поместить переменные в каждую функцию в другом порядке в стеке, или он может решить обнулить стек, используемый функцией после возвращения функции.
Выявление неинициализированного указателя является неопределенным поведением. Он может печатать любую ценность. –
В ответ на вопрос «Почему?» print '* p' показывает значение, введенное в' x': это неопределенное поведение, поэтому компилятор может что-либо сделать, и вы не можете положиться на него ... но в этом конкретном случае с этим выравниванием планет, вероятно, компилятор просто сохраняет адрес '& x' в регистре и читает обратно, вместо недействительного' p'.Честно: любая попытка прочитать из неинициализированной переменной UB и может что-то сделать или ничего, или что-то хорошее, или что-то плохое ... и т. Д. –
Я знаю, что p в первой и второй функции p другой. Мой вопрос в том, почему * p во второй функции получает значение x? –