Błąd: „GDB nie może uzyskać dostępu do pamięci pod adresem” w C++

Blad Gdb Nie Moze Uzyskac Dostepu Do Pamieci Pod Adresem W C



Debugowanie jest istotną częścią procesu tworzenia aplikacji w C++ lub innym języku programowania. Tworzenie aplikacji w C++ nie jest łatwe; wymaga to dobrych umiejętności w zakresie struktury danych, umiejętności naprawiania błędów i zarządzania narzędziami do debugowania. GDB, GNU Debugger, to wydajne narzędzie, które pomaga programistom identyfikować i naprawiać błędy w kodzie. GDB to ciekawie proste i przydatne narzędzie, które pomaga programistom znajdować i naprawiać błędy w kodzie.

Jednakże podczas korzystania z GDB może pojawić się błąd „błąd: GDB nie może uzyskać dostępu do pamięci pod adresem”. Ten błąd może być mylący i utrudniać dalsze debugowanie. W tym artykule skupiono się na określeniu przyczyny wystąpienia tego błędu i przyjrzeniu się przykładom kodu, które pomagają nam zrozumieć, jak rozwiązać ten błąd.

Przykład 1:

Zobaczmy nasz pierwszy przykład kodu, który po wykonaniu wyświetla błąd „GDB nie może uzyskać dostępu do pamięci pod adresem”. Najpierw patrzymy na kod. Następnie zobaczymy wyjaśnienie linijka po linijce.







#include
za pomocą przestrzeń nazw st ;
wew główny ( próżnia ) {
wew * P ;
cout << * P ;
}

Program rozpoczyna się od deklaracji dyrektywy preprocesora „#include ” i użycia „przestrzeni nazw std”, które są niezbędne do uwzględnienia w programie, aby móc korzystać ze standardowych funkcji wejścia i wyjścia. Następnie pojawia się główny punkt wejścia, czyli „int main(void);”. Ta linia deklaruje punkt początkowy programu.



W ramach funkcji main deklarowana jest zmienna wskaźnikowa „*p”. Tutaj zmienna „p” nie jest inicjowana. Dlatego nie wskazuje żadnego konkretnego miejsca w pamięci zarezerwowanego dla liczby całkowitej. Ta linia powoduje błąd, który naprawimy później. W kolejnej linii próbujemy wydrukować wartość zmiennej „*p” za pomocą instrukcji „cout”.



Ponieważ zmienna „p” jest wskaźnikiem typu całkowitego, do jej usunięcia używana jest gwiazdka „*”. Oznacza to, że wartość znajduje się w miejscu pamięci, na które wskazuje. Ponieważ jednak wskaźnik „p” nie został zainicjowany i nie wskazuje żadnej konkretnej i prawidłowej lokalizacji, wyłuskanie wskaźnika spowoduje niezdefiniowane zachowanie. Powoduje to generowanie różnego rodzaju błędów w zależności od systemu i kompilatora. Ponieważ do debugowania i uruchamiania tego programu używamy kompilatora GDB, debuger zgłosi następujący błąd. Błąd jest pokazany we fragmencie wyjściowym:





Jak widać na wynikach, debuger nie może uzyskać dostępu do pamięci. Ten program odwołuje się do niezainicjowanego wskaźnika, co jest główną przyczyną tego niezdefiniowanego zachowania. Zobaczmy teraz, jak możemy rozwiązać ten problem. Poprawny kod podano poniżej. Przyjrzyj się temu, a wyjaśnimy, jak naprawić błąd w kodzie:



#include
za pomocą przestrzeń nazw st ;
wew główny ( próżnia ) {
wew wal = 5 ;
wew * P = & wal ;
cout << „Wartość to =” << * P ;

}

Jak widać, kod jest modyfikowany poprzez dodanie „int val =5;” oświadczenie. Ta linia deklaruje zmienną całkowitą o nazwie „val” i inicjuje ją wartością „5”. Następna linia, „int *p = &val;”, deklaruje zmienną wskaźnikową „*p” i jest inicjowana tak, aby wskazywała adres zmiennej „val”. Poprzednio wskaźnik „*p” nie wskazywał żadnego adresu pamięci, co powodowało, że „nie można uzyskać dostępu do pamięci pod adresem 0x0”.

Aby rozwiązać ten problem, deklaruje się, inicjuje zmienną „var” i przypisuje ją do wskaźnika „*p”. Teraz wskaźnik „*p” wskazuje adres zmiennej „val”, ponieważ operator „&” pobiera adres „val” i przypisuje go do „p”. Ponownie, instrukcja „cout” służy do wydrukowania wartości wskaźnika „*p”. Zobacz poniższy fragment kodu wyjściowego, aby zobaczyć wartość „val”, do której dostęp uzyskuje wskaźnik „*p”:

Jak widać, błąd został naprawiony i zainicjowana została wartość „5”, ponieważ zmienna „val” została wydrukowana poprzez wywołanie wskaźnika „*p” valribale.

Przykład 2:

Rozważmy inny przykład wyjaśniający, jak zaspokoić błąd „GDB nie może uzyskać dostępu do pamięci pod adresem” w programie kodującym C++. Kod podano poniżej w celach informacyjnych. Spójrz:

#include
wew główny ( ) {
wew * P = nowy wew [ piętnaście ] ;
usuwać [ ] P ;
st :: cout << P [ 2 ] << st :: koniec ;
powrót 0 ;
}

Jednym z najczęstszych scenariuszy, z jakimi spotykają się programiści podczas programowania ze wskaźnikami, jest nieprawidłowa lub niewłaściwa alokacja pamięci. GDB powoduje błąd za każdym razem, gdy w programie C++ wystąpi niepoprawna alokacja i dezalokacja pamięci.

Biorąc pod uwagę poprzedni przykład kodu, wskaźnik „*p” jest inicjowany nową liczbą typu int[15]. Ta instrukcja dynamicznie przydziela tablicę 15 liczb całkowitych przy użyciu operatora new. Zmienna wskaźnikowa „*p” przechowuje adres pamięci tablicy.

W poniższej instrukcji „delete[] p;” stwierdza, że ​​pamięć została zwolniona za pomocą polecenia Delete[]. Komenda Delete[] zwalnia wcześniej przydzieloną pamięć wskaźnika „*p”, co oznacza, że ​​inny system może ponownie przydzielić wcześniej przydzielony blok pamięci. Kiedy spróbujemy wydrukować wartość zmiennej „*p” za pomocą instrukcji „cout”, otrzymamy błąd dostępu do pamięci, co widać na następującym wyjściu:

Należy pamiętać, że dokładny komunikat o błędzie może się nieznacznie różnić w zależności od wersji GDB i systemu. Ale „błąd: GDB nie może uzyskać dostępu do pamięci w tej lokalizacji” i błąd podany w poprzednim fragmencie są takie same. Aby rozwiązać ten błąd, po prostu przesuwamy polecenie usuwania [] po instrukcji „cout”. Zobacz zmodyfikowany kod poniżej:

#include
wew główny ( ) {
wew * P = nowy wew [ piętnaście ] ;
Do ( wew I = 0 ; I < piętnaście ; ++ I ) {
P [ I ] = I * 2 - 5 + 8 ;
st :: cout << 'P[' << I << '] = ' << P [ I ] << st :: koniec ;
}
usuwać [ ] P ;
powrót 0 ;
}

Tutaj możesz zobaczyć, że zainicjowaliśmy tablicę wartościami, które są obliczane w czasie wykonywania, a wszystkie wartości pętli wypisujemy za pomocą pętli „for”. Najważniejszą rzeczą, na którą należy zwrócić uwagę, jest przesunięcie instrukcji Delete[]; jest teraz wywoływany po pobraniu wszystkich wartości tablicy, co usunęło błąd dostępu do pamięci. Zobacz końcowy wynik kodu w następujący sposób:

Wniosek

Podsumowując, błąd „błąd: GDB nie może uzyskać dostępu do pamięci pod adresem” zwykle wskazuje na problemy związane z pamięcią w kodzie C++. W tym artykule omówiono kilka typowych scenariuszy inicjujących ten błąd, aby wyjaśnić, kiedy i jak można go rozwiązać. Kiedy ten błąd wystąpi w kodzie, należy go dokładnie przejrzeć, zwracając szczególną uwagę na zmienne wskaźnikowe, alokację pamięci, tablice i struktury.

Co więcej, funkcje takie jak punkty przerwania udostępniane przez GDB mogą pomóc w zlokalizowaniu błędu podczas debugowania programu. Funkcje te mogą pomóc w określeniu dokładnej lokalizacji błędów związanych z pamięcią. Proaktywnie rozwiązując te problemy, programiści mogą zwiększyć stabilność i niezawodność swoich aplikacji C++.