Próbuję zrozumieć ramkę stosu w C, więc napisałem prosty kod C, aby przeanalizować ramkę stosu.Zrozumienie ramek stosu w C
Przede wszystkim fun1() zwraca adres zmiennej lokalnej, który jest inicjowany do 10 do ptr co prowadzi do ostrzeżenia, ale to jest ok ... Jeśli mogę wydrukować wartość * ptr teraz drukuje 10, nawet to w porządku ...
Następna fun2() zwraca adres zmiennej lokalnej, która nie została zainicjalizowana i jeśli spróbuję wydrukować wartość * ptr, teraz drukuje 10 bez względu na to, czy jestem zwracając adres a lub b ...
Aby zrozumieć, co się tutaj dzieje, skorzystałem z gdb. Korzystanie z gdb, zacząłem krok po kroku debugowania i kiedy osiągnął linię „zwrot &” w fun2(), próbowałem wydrukować adres B, drukiem & b ale drukowane nie potrafisz przyjąć adres "b", który nie jest lwartością.
nie rozumiem, gdy próbuję wydrukować adresu, druku & drukuje absolutnie w porządku, to dlaczego nie adres b. * Dlaczego nie ma b lwartości, gdy a jest?
# include <stdio.h>
int * fun1() {
int a = 10;
return &a;
}
int * fun2()
{
int a;
int b;
return &a; // return &b;
}
int main()
{
int *ptr;
ptr = fun1();
ptr = fun2();
printf ("*ptr = %d, fun2() called...\n", *ptr);
return 0;
}
http://stackoverflow.com/a/18479996/1814023 –
pan powołując niezdefiniowanej zachowanie. Nie ma gwarancji, że wyniki będą miały jakikolwiek sens, lub zrobią to, czego można oczekiwać od układu stosu. Standardowa hiperbola polega na tym, że program może zrobić [demony] (http://www.catb.org/jargon/html/N/nasal-demons.html) wyskoczyć z nosa. – user2357112
Masz szczęście, że drukowanie '* ptr' drukuje 10; na pewno nie jest to gwarantowane (przywołujesz niezdefiniowane zachowanie). Ale naprawdę powinieneś pokazać cały kod. W kodzie kompilator prawdopodobnie upuścił 'b' jako nieużywaną zmienną, więc nie ma lokalizacji, dlatego nie można wziąć jej adresu. Użyj 'b' w kodzie, w jakiś sposób, i będziesz mógł go wydrukować. I proszę, nie zgłaszaj "czegoś w stylu"; być precyzyjnym i dokładnie raportować, co mówi debugger. –