Это не то поведение, на которое вы можете положиться; он может и, вероятно, будет отличаться в разных системах, даже в разных версиях компилятора или разных переключателях компилятора.
Учитывая это, вероятно, происходит следующее: fun возвращает указатель на место хранения k. Эта часть стека больше не является надежной, потому что функция, выделившая ее, завершила работу. Тем не менее, никто еще не переписал его, поэтому 4 все еще там, где он был написан. Затем main готовится вызвать printf. Для этого он получает первый аргумент *ptr. Для этого он загружается с точки ptr места, которая является (бывшим) адресом k, поэтому в нагрузку попадает та 4, которая там есть. Эти 4 хранятся в регистре или стеке для передачи в printf. Затем адрес строки формата "%d" сохраняется для передачи в printf. Затем вызывается printf. В этот момент printf использует большой объем стека и записывает новые данные там, где раньше было k. Однако число 4, которое было передано в качестве аргумента, находится в безопасном месте, где должны быть аргументы для printf, поэтому printf напечатает его. Затем printf возвращается. Затем основная процедура готовится снова вызвать printf. На этот раз, когда он загружается с того места, где указывает ptr, 4 больше нет; это какое-то значение, которое было записано во время первого вызова printf. Таким образом, это значение передается в printf и печатается.
Никогда не пишите код, который использует это поведение. Это ненадежно и не является правильным кодом.
person
Eric Postpischil
schedule
27.07.2012