Używanie ciągów C daje ostrzeżenie „Adres pamięci stosu powiązanego z zwróconą zmienną lokalną” - naprawa

Używanie ciągów C daje ostrzeżenie „Adres pamięci stosu powiązanego z zwróconą zmienną lokalną” - naprawa
Jeden z najczęstszych ostrzeżenia Może się to zdarzyć podczas korzystania z języka programowania C to „Adres stosu powiązany z zwróconą zmienną lokalną". Ten ostrzeżenie może wystąpić, gdy pamięć powiązana z zmienną lokalną jest dostępna po jej ustaleniu. Innymi słowy, odniesienie zmiennej lokalnej nie jest już stabilne. Aby lepiej to zrozumieć ostrzeżenie, Ważne jest, aby zrozumieć koncepcję pamięci stosu i sposób, w jaki odnosi się ona do zmiennych lokalnych.

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ąć.