Co to jest błąd segmentacji? Czy jest inaczej w C i C ++? W jaki sposób powiązane są błędy segmentacji i zwisające wskaźniki?
c++
c
segmentation-fault
Rajendra Uppal
źródło
źródło
NullPointerException
.Odpowiedzi:
Błąd segmentacji to szczególny rodzaj błędu spowodowanego dostępem do pamięci, która „nie należy do ciebie”. Jest to mechanizm pomocniczy, który chroni przed uszkodzeniem pamięci i wprowadzaniem trudnych do debugowania błędów pamięci. Za każdym razem, gdy pojawia się awaria, wiesz, że robisz coś złego z pamięcią - uzyskujesz dostęp do zmiennej, która została już zwolniona, zapisujesz w części pamięci tylko do odczytu itp. Błąd segmentacji jest zasadniczo taki sam w większości języków, które pozwalają na bałagan z zarządzanie pamięcią, nie ma zasadniczej różnicy między segfault w C i C ++.
Istnieje wiele sposobów, aby uzyskać awarię, przynajmniej w językach niższego poziomu, takich jak C (++). Typowym sposobem na uzyskanie segfault jest wyzerowanie wskaźnika zerowego:
Kolejna awaria zdarza się, gdy próbujesz zapisać w części pamięci oznaczonej jako tylko do odczytu:
Zwisający wskaźnik wskazuje na rzecz, która już nie istnieje, jak tutaj:
Wskaźnik
p
zwisa, ponieważ wskazuje na zmiennąc
znakową, która przestała istnieć po zakończeniu bloku. A kiedy spróbujesz wyrejestrować zwisający wskaźnik (jak*p='A'
), prawdopodobnie dostaniesz awarię.źródło
c
jest lokalny, oznacza to, że został on wypchnięty na stos później{
i wyskakuje z niego później}
. zwisający wskaźnik jest tylko odniesieniem do przesunięcia, które jest teraz poza stosem. dlatego modyfikowanie go w prostym programie nigdy nie wywoła żadnej awarii. z drugiej strony może to prowadzić do segfaultu w bardziej złożonym przypadku użycia, gdzie inne wywołania funkcji mogą prowadzić do wzrostu stosu i przechowywania danych wskazanych przez wiszący wskaźnik. zapisywanie do tych danych (lokalne zmienne) prowadziłoby do nieokreślonego zachowania (segfault & Co)SIGSEGV
, więc nie oczekuję, że taki sygnał zakłócałby się ze stosem.Warto zauważyć, że błąd segmentacji nie jest spowodowany bezpośrednim dostępem do innej pamięci procesu (to właśnie czasami słyszę), ponieważ jest to po prostu niemożliwe. Dzięki pamięci wirtualnej każdy proces ma własną wirtualną przestrzeń adresową i nie ma możliwości uzyskania dostępu do innej za pomocą dowolnej wartości wskaźnika. Wyjątkiem mogą być biblioteki współdzielone, które są tą samą fizyczną przestrzenią adresową odwzorowaną na (ewentualnie) różne adresy wirtualne i pamięć jądra, która jest nawet odwzorowana w ten sam sposób w każdym procesie (myślę, aby uniknąć opróżniania TLB podczas syscall). I takie rzeczy jak shmat;) - to, co uważam za dostęp „pośredni”. Można jednak sprawdzić, czy zwykle znajdują się one z dala od kodu procesu i zazwyczaj jesteśmy w stanie uzyskać do nich dostęp (dlatego tam są,
Mimo to błąd segmentacji może wystąpić w przypadku niewłaściwego dostępu do naszej (procesowej) pamięci (na przykład próby zapisu w przestrzeni, której nie można zapisać). Ale najczęstszym powodem jest dostęp do części wirtualnej przestrzeni adresowej, która w ogóle nie jest odwzorowana na fizyczną.
A wszystko to w odniesieniu do systemów pamięci wirtualnej.
źródło
Błąd segmentacji jest spowodowany żądaniem strony, której proces nie ma na liście w tabeli deskryptorów, lub nieprawidłowym żądaniem strony, którą ma na liście (np. Żądanie zapisu na stronie tylko do odczytu).
Zwisający wskaźnik to wskaźnik, który może, ale nie musi wskazywać prawidłowej strony, ale wskazuje „nieoczekiwany” segment pamięci.
źródło
Szczerze mówiąc, jak wspomnieli inni plakaty, Wikipedia ma na ten temat bardzo dobry artykuł, więc zajrzyj tam. Ten typ błędu jest bardzo powszechny i często nazywany innymi rzeczami, takimi jak naruszenie dostępu lub ogólny błąd ochrony.
Nie różnią się niczym w C, C ++ ani żadnym innym języku, który pozwala na korzystanie ze wskaźników. Tego rodzaju błędy są zwykle powodowane przez wskaźniki
źródło
Według wikipedii:
źródło
Błąd segmentacji jest również spowodowany awarią sprzętu, w tym przypadku pamięci RAM. Jest to mniej powszechna przyczyna, ale jeśli nie znajdziesz błędu w kodzie, być może pomoże ci memtest.
Rozwiązaniem w tym przypadku jest zmiana pamięci RAM.
edytować:
Oto odniesienie: Błąd segmentacji według sprzętu
źródło
Błąd segmentacji występuje, gdy proces (działająca instancja programu) próbuje uzyskać dostęp do adresu pamięci tylko do odczytu lub zakresu pamięci, który jest używany przez inny proces lub uzyskać dostęp do nieistniejącego (niepoprawnego) adresu pamięci. Problem Dangling Reference (wskaźnik) oznacza, że próba uzyskania dostępu do obiektu lub zmiennej, której zawartość została już usunięta z pamięci, np .:
źródło
Strona błędu segmentacji Wikipedii ma bardzo ładny opis na ten temat, podając tylko przyczyny i przyczyny. Szczegółowy opis znajduje się na wiki.
W obliczeniach błąd segmentacji (często skracany do segfault) lub naruszenie dostępu to błąd zgłaszany przez sprzęt z ochroną pamięci, powiadamiający system operacyjny (OS) o naruszeniu dostępu do pamięci.
Oto niektóre typowe przyczyny błędu segmentacji:
Te z kolei są często spowodowane błędami programowania, które powodują nieprawidłowy dostęp do pamięci:
Dereferencje lub przypisywanie do niezainicjowanego wskaźnika (dziki wskaźnik, który wskazuje na losowy adres pamięci)
Dereferencje lub przypisywanie do zwolnionego wskaźnika (zwisający wskaźnik, który wskazuje na pamięć, która została zwolniona / cofnięta / usunięta)
Przepełnienie bufora.
Przepełnienie stosu.
Próba uruchomienia programu, który nie kompiluje się poprawnie. (Niektóre kompilatory generują plik wykonywalny pomimo obecności błędów czasu kompilacji).
źródło
Krótko mówiąc: błąd segmentacji to system operacyjny wysyłający do programu sygnał informujący, że wykrył nielegalny dostęp do pamięci i przedwcześnie kończy działanie programu, aby zapobiec uszkodzeniu pamięci.
źródło
„Błąd segmentacji” oznacza, że próbowałeś uzyskać dostęp do pamięci, do której nie masz dostępu.
Pierwszy problem dotyczy twoich argumentów main. Główną funkcją powinno być
int main(int argc, char *argv[])
i powinieneś sprawdzić, czy argc wynosi co najmniej 2, zanim uzyskasz dostęp do argv [1].Ponadto, ponieważ przekazujesz liczbę zmiennoprzecinkową do printf (która, nawiasem mówiąc, przekształca się w podwójną podczas przekazywania do printf), powinieneś użyć specyfikatora formatu% f. Specyfikator formatu% s dotyczy ciągów znaków (tablice znaków zakończone „\ 0”).
źródło
Błąd segmentacji lub naruszenie dostępu występuje, gdy program próbuje uzyskać dostęp do miejsca pamięci, które nie istnieje lub próbuje uzyskać dostęp do miejsca pamięci w sposób niedozwolony.
Tutaj ja [1000] nie istnieje, więc występuje błąd.
Przyczyny błędu segmentacji:
źródło
Istnieje kilka dobrych wyjaśnień „błędu segmentacji” w odpowiedziach, ale ponieważ w przypadku błędu segmentacji często występuje zrzut zawartości pamięci, chciałem się podzielić, gdzie jest relacja między częścią „zrzuconego rdzenia” w usterce segmentacji (zrzucony rdzeń) i pamięć pochodzi z:
Zabrano stąd .
źródło
Jest wystarczająco dużo definicji błędu segmentacji, chciałbym zacytować kilka przykładów, które napotkałem podczas programowania, które mogą wydawać się głupimi błędami, ale zmarnują dużo czasu.
możesz otrzymać błąd segmentacji w poniższym przypadku, podczas gdy niedopasowanie typu argumet w printf
#include<stdio.h> int main(){
int a = 5; printf("%s",a); return 0; }
wynik :
Segmentation Fault (SIGSEGV)
gdy zapomniałeś przydzielić pamięć wskaźnikowi, ale próbujesz go użyć.
wynik :
Segmentation Fault (SIGSEGV)
źródło
Proste znaczenie
Segmentation fault
polega na tym, że próbujesz uzyskać dostęp do pamięci, która nie należy do ciebie.Segmentation fault
występuje, gdy próbujemy czytać i / lub pisać zadania w miejscu pamięci tylko do odczytu lub próbujemy zwolnić pamięć. Innymi słowy, możemy to wyjaśnić jako pewnego rodzaju uszkodzenie pamięci.Poniżej wymienię typowe błędy popełniane przez programistów, które do nich prowadzą
Segmentation fault
.scanf()
w niewłaściwy sposób (zapomniałem umieścić&
).printf()
iscanf()
„źródło