Zmienne lokalne są przechowywane w formie pamięci zwanej pamięcią stosu. Za każdym razem, gdy wywołuje funkcja, zmienne lokalne zadeklarowane w funkcji są przechowywane na stosie w określonej kolejności. Gdy połączenie funkcyjne kończy się, zmienne lokalne są usuwane ze stosu w przeciwnej kolejności, a adres pamięci powiązany ze zmiennymi lokalnymi nie jest już poprawny. Wskazuje to, że zmiennej lokalnej nie można już uzyskać dostępu za pomocą wcześniej używanego wskaźnika.
Przyczyny ostrzeżenia
Powody, dla których to ostrzeżenie może wystąpić:
1: Nie z zakresu
Jeśli wskaźnik jest używany do uzyskania dostępu do zmiennej lokalnej po zniknięciu adresu zmiennej lokalnej poza zakresem, „„Adres stosu powiązany z zwróconą zmienną lokalną”Zostanie rzucony. Może się to zdarzyć, jeśli wskaźnik używany do dostępu do zmiennej lokalnej nie jest prawidłowo zarządzany lub jeśli funkcja jest opuszczana przed użyciem wskaźnika. Aby rozwiązać ten problem, wskaźnik musi zostać najpierw sprawdzony, aby upewnić się, że jest on ważny. Po potwierdzeniu, że wskaźnik jest prawidłowy, wskaźnik musi być poprawnie obsługiwany. Jeśli wskaźnik nie jest odpowiednio obsługiwany, ostrzeżenie będzie trwał.
Na koniec należy zauważyć, że „Adres stosu powiązany z zwróconą zmienną lokalną”Może być również spowodowane przez inne ostrzeżenia, takie jak przepełnienie stosu, w którym stos jest wypełniony większą liczbą zmiennych niż może trzymać. Jeśli nastąpi przepełnienie stosu, ważne jest, aby naprawić problem podstawowy, który spowodował przepełnienie stosu, aby upewnić się, że „Adres stosu powiązany z zwróconą zmienną lokalną”Nie jest rzucany.
Spójrz na ten przykład:
#włączać
char* getString ()
char S [100];
printf („wprowadź ciąg:”);
Scanf („%s”, s);
zwroty;
int main ()
char* s = getString ();
printf („Wpisałeś: %s \ n”, s);
powrót 0;
getString () Metoda tworzy lokalną tablicę str na stosie w tym przykładzie i używa scanf () Aby odczytać ciąg od użytkownika.Następnie funkcja zwraca wskaźnik do tej zmiennej lokalnej Str. Zwrócony wskaźnik jest przypisany do S w główny() metoda i jest drukowana za pomocą printf (). Niemniej jednak str jest lokalną zmienną na stosie, a jej pamięć nie jest już użyteczna, gdy getTring () Metoda wychodzi, doprowadzi to do nieokreślonego zachowania.
Wyjście
Możemy użyć Malloc () lub podobna metoda do dynamicznego przydzielania pamięci dla ciągu i zwrócenie odniesienia do tej nowo utworzonej pamięci, aby temu zapobiec ostrzeżenie i następujące niezdefiniowane zachowanie. Oto ilustracja tego, jak zmienić poprzedni kod, aby pozbyć się ostrzeżenie:
#włączać
#włączać
char* getString ()
char * s = malloc (100 * sizeof (char));
printf („wprowadź ciąg:”);
Scanf („%s”, s);
zwroty;
int main ()
char* s = getString ();
printf („Wpisałeś: %s \ n”, s);
wolne (s);
powrót 0;
W powyższym zaktualizowanym kodzie dynamicznie przydzielamy 100 bajtów pamięci dla łańcucha za pomocą Malloc () i zwróć odniesienie do tej pamięci. Kiedy będziemy korzystać z pamięci, dzwonimy bezpłatny() Aby go wydać. Zachowujemy ostrzeżenie i gwarantujemy, że RAM, którego używamy, jest ważny na czas trwania naszej aplikacji.
Wyjście
2: Niewłaściwa deklaracja zmiennych lokalnych
Oprócz zapewnienia prawidłowego obsługi wskaźnika, ważne jest również, aby upewnić się, że zmienne lokalne są prawidłowo zadeklarowane. Jeśli zmienne są zadeklarowane w niewłaściwej kolejności lub jeśli zmienne są zadeklarowane w niewłaściwym czasie, może wystąpić ostrzeżenie. Na przykład, jeśli zmienna lokalna zostanie zadeklarowana po zakończeniu funkcji, wówczas adres zmiennej lokalnej nie będzie już poprawny.
#włączać
int* add (int a, int b)
int sum = a + b;
zwrócić ∑
int main ()
Int* Adres = Add (5, 6);
Kompilator uniemożliwia funkcję zwracanie adresu suma od suma został zdefiniowany i zainicjowany w bloku funkcyjnym, co czyni ją zmienną lokalną (za pomocą i operatora). Wszystkie zmienne lokalne są usuwane natychmiast, gdy funkcja kończy się, dlatego instrukcja powrotu nie powinna zwracać wskaźnika zawierającego lokalizację zmiennej lokalnej (suma). Jeśli nie, wskaźnik będzie wskazywał na część pamięci, na której nie masz już kontroli.
Wyjście
Adres zwrotny jest zmienną lokalną, co jest problemem.Poprawieniem jest przekazanie adresu jako parametru do funkcji i dynamicznie przydzielić pamięć do zmiennej, aby ją utrzymać. Zmienna nie jest już zmienną lokalną, ponieważ została zdefiniowana poza blokiem funkcji.
Zobacz kod tutaj:
#włączać
#włączać
int* add (int a, int b, int* sum)
*sum = a + b;
suma zwrotu;
int main ()
int* sum = malloc (sizeof (int));
Dodaj (5, 6, suma);
printf („Sum %d jest przechowywany pod adresem %p \ n”, *sum, (void *) suma);
darmowe (suma);
powrót 0;
Powyższy kod używa Malloc () funkcja przeznaczania pamięci dla liczby całkowitej i dodać() Funkcja odbiera odniesienie do tej pamięci jako parametr sum. Funkcja mnoży się A I B, Zapisuje wynik w pamięci, o której mowa, a następnie zwraca sumę. Zgłaszamy wartość i lokalizację liczby całkowitej, o której mowa w sumie główny(). Aby zatrzymać wycieki pamięci, używamy następnie bezpłatny() Aby uwolnić pamięć, którą przydzielono Malloc.
Wyjście
Wniosek
„„Adres stosu powiązany z zwróconą zmienną lokalną”Jest ostrzeżeniem, które może wystąpić, gdy wskaźnik do zmiennej lokalnej jest używany po tym, jak adres zmiennej lokalnej zniknie z zakresu. Aby zapobiec wystąpieniu tego ostrzeżenia, ważne są odpowiednie zarządzanie wskaźnikami i lokalne deklaracje zmiennych. Ważne jest również, aby potwierdzić, że żadne inne ostrzeżenia nie powodują przepełnienia stosu. Postępując zgodnie z tymi wytycznymi, „Adres stosu powiązany z zwróconą zmienną lokalną" można uniknąć.