2014-10-14 4 views
-2

В контексте того, что написано в этой статьепеременные в стеке и Heap

http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html#sec-6

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

Таким образом, все переменные, которые принадлежат к этой функции в стеке выталкивается, за исключением может быть значение, которое возвращается к функции (или, может быть перераспределены для родительской функции?), Или если она не статична ,

Но эта конкретная программа работает полностью нормально.

#include<stdio.h> 

int* func() 
{ 
int a=6; 
int *b; 
b=&a; 
printf("in func - %d \n",*b); 

return b; 
} 

void func2() 
{ 
    int a,c; 
    a=99; 
    c=2*a; 
    printf("in func 2 - %d \n",c); 
} 

void main() 
{ 
int *b; 
b=func(); 
func2(); 
printf("in main - %d",*b); 
} 

Выход:

C:\Users\Shaurya\Desktop>gcc asw.c 

C:\Users\Shaurya\Desktop>a 
in func - 6 
in func 2 - 198 
in main - 6 
C:\Users\Shaurya\Desktop> 

Я полагал, переменные, которые распределены пользователем (с помощью calloc, таНос, перераспределить) доступен для других функций, потому что они находятся в куче, как говорится в статье. Но если мы сделаем указатель на локальную переменную, находящуюся в стеке, и вернем этот указатель, то и переменная будет доступна в другой функции.

+3

Никогда. Когда-либо. Сказать. «Совершенно точно». –

+1

Попробуйте вызвать другую функцию между вызовами 'func' и' printf'. –

+1

Один из моих любимых: http://stackoverflow.com/a/6445794/1382251 –

ответ

3

Возвращая адрес локальной переменной (и пытается разыменования его в вызывающей), ваша программа вызывает неопределенное поведение. Одним из возможных результатов неопределенного поведения является то, что ваша программа работает правильно. Однако, если вы измените свой код для вызова другой функции (особенно той, которая создает и устанавливает локальные переменные) между вызовами func и printf, вы, вероятно, получите другой результат.

Ячейка памяти a что используется оккупировать очевидно, все еще существует, и будет содержать последнее значение a, пока что-то еще не перезаписывает его. Вы только что получили доступ к этой ячейке памяти, прежде чем что-либо еще дошло до нее.


1. Мы говорим о виртуальной памяти здесь, а не о физической памяти.

+0

Кажется не работает. Должен ли я попробовать большую функцию? Результаты были опубликованы как редактирование. –

+0

@John Bode Непонятно, почему «память» сноска. Ячейка памяти, которая 'a' использовала, все еще существует, даже если физическая память, и будет содержать последнее значение' a', пока что-то не перезапишет его (или цикл питания). – chux

+1

@ShauryaChaudhuri: Это может быть любое количество причин; опять же, точка зрения заключается в том, что поведение 'func' равно * undefined *, и практически любой результат (включая корректное отображение) возможен. Вы не должны полагаться на то, что это поведение повторяемо или предсказуемо. Возвращая адрес переменной 'auto' и пытаясь разыменовать его всю жизнь переменной, это ошибка кодирования, полная остановка. –

1

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

+0

Кажется, не работает. Должен ли я попробовать большую функцию? Результаты были опубликованы как редактирование. –

+0

@ShauryaChaudhuri Извините, я вернулся к этому поздно, но все важные комментарии были сделаны в другом ответе :) –

Смежные вопросы