Segmenteringsfeil i C eller C++ er en feil som oppstår når et program prøver å få tilgang til en minneplassering det ikke har tilgang til. Vanligvis oppstår denne feilen når minnetilgangen brytes og er en type generell beskyttelsesfeil. Segfaults er forkortelsen for segmenteringsfeil.
De kjernedump refererer til registrering av tilstanden til programmet, dvs. ressursene i minnet og prosessoren. Å prøve å få tilgang til ikke-eksisterende minne eller minne som brukes av andre prosesser forårsaker også segmenteringsfeilen som fører til en kjernedump.
Et program har tilgang til bestemte områder av minnet mens det kjører. Først brukes stabelen til å holde de lokale variablene for hver funksjon. Dessuten kan det ha minne tildelt under kjøring og lagret på heapen (ny i C++, og du kan også høre at det kalles gratis butikk ). Det eneste minnet som programmet har tilgang til er dets eget (minnet som er nevnt tidligere). En segmenteringsfeil vil oppstå fra all tilgang utenfor den regionen.
Segmenteringsfeil er en spesifikk type feil forårsaket av tilgang til minne som tilhører ikke deg :
- Når et stykke kode prøver å gjøre en lese-og-skrive-operasjon på et skrivebeskyttet sted i minnet eller frigjort minneblokk, er det kjent som en segmenteringsfeil.
- Det er en feil som indikerer minnekorrupsjon.
Vanlige segmenteringsfeilscenarier
I en segmenteringsfeil prøver et program å få tilgang til minne som ikke er autorisert til å få tilgang til, eller som ikke eksisterer. Noen vanlige scenarier som kan forårsake segmenteringsfeil er:
- Endre en streng bokstavelig
- Tilgang til en adresse som er frigjort
- Få tilgang til indeksgrenser utenfor arrayet
- Feil bruk av scanf()
- Stack Overflow
- Fjernerererer ikke initialisert peker
1. Endre en streng bokstavelig
Strengeliteralene lagres i den skrivebeskyttede delen av minnet. Det er grunnen til at programmet nedenfor kan krasje (gir segmenteringsfeil) fordi linjen *(str+1) = 'n' prøver å skrive et skrivebeskyttet minne.
Eksempel:
C
// C program to demonstrate segmentation fault> // by modifying a string literal> #include> int> main()> {> >char>* str;> >// Stored in read only part of data segment //> >str =>'GfG'>;> >// Problem: trying to modify read only memory //> >*(str + 1) =>'n'>;> >return> 0;> }> |
>
>
C++
// C++ program to demonstrate segmentation fault> // by modifying a string literal> #include> using> namespace> std;> int> main()> {> >char>* str;> >// Stored in read only part of data segment //> >str =>'GfG'>;> >// Problem: trying to modify read only memory //> >*(str + 1) =>'n'>;> >return> 0;> }> |
>
>
Produksjon
timeout: den overvåkede kommandoen dumpet kjernen
/bin/bash: linje 1: 32 Segmenteringsfeil tidsavbrudd 15 s ./83b16132-8565-4cb1-aedb-4eb593442235 <83b16132-8565-4cb1-aedb-4eb593442235.in.
Se Lagring for strenger i C for flere detaljer.
2. Tilgang til en adresse som er frigjort
Her i koden nedenfor blir pekeren p derferert etter frigjøring av minneblokken, noe som ikke er tillatt av kompilatoren. Slike pekere kalles hengende pekere, og de produserer segmentfeil eller unormal programavslutning under kjøring.
Eksempel:
C
// C program to demonstrate segmentation fault> // by Accessing an address that is freed> #include> #include> int> main(>void>)> {> >// allocating memory to p> >int>* p = (>int>*)>malloc>(8);> >*p = 100;> >// deallocated the space allocated to p> >free>(p);> >// core dump/segmentation fault> >// as now this statement is illegal> >*p = 110;> >printf>(>'%d'>, *p);> >return> 0;> }> |
eksempel binært søketre
>
>
C++
// C++ program to demonstrate segmentation fault> // by Accessing an address that is freed> #include> using> namespace> std;> int> main(>void>)> {> >// allocating memory to p> >int>* p = (>int>*)>malloc>(>sizeof>(>int>));> >*p = 100;> >// deallocated the space allocated to p> >free>(p);> >// segmentation fault> >// as now this statement is illegal> >*p = 110;> >return> 0;> }> |
>
>
Produksjon
Segmentation Fault>
3. Få tilgang til Out-of-bounds Array Index
I C og C++ kan tilgang til en out-of-bounds array-indeks forårsake en segmenteringsfeil eller annen udefinert oppførsel. Det er ingen grensekontroll for matriser i C og C++. Selv om det er i C++, kan bruken av containere som med std::vector::at()-metoden eller med en if()-setning, forhindre out-of-bound feil.
Eksempel:
C
// C program to demonstrate segmentation> // fault when array out of bound is accessed.> #include> int> main(>void>)> {> >int> arr[2];> >// Accessing out of bound> >arr[3] = 10;> >return> (0);> }> |
>
>
C++
// C++ program to demonstrate segmentation> // fault when array out of bound is accessed.> #include> using> namespace> std;> int> main()> {> >int> arr[2];> >// Accessing out of bound> >arr[3] = 10;> >return> 0;> }> |
>
>
Produksjon
Segmentation Faults>
4. Feil bruk av scanf()
scanf()-funksjonen forventer adressen til en variabel som input. Her i dette programmet tar n verdien 2 og antar sin adresse som 1000. Hvis vi sender n til scanf(), blir input hentet fra STDIN plassert i ugyldig minne 2 som skal være 1000 i stedet. Dette forårsaker minnekorrupsjon som fører til en segmenteringsfeil.
Eksempel:
C
// C program to demonstrate segmentation> // fault when value is passed to scanf> #include> int> main()> {> >int> n = 2;> >scanf>(>'%d'>, n);> >return> 0;> }> |
>
>
C++
// C++ program to demonstrate segmentation> // fault when value is passed to scanf> #include> using> namespace> std;> int> main()> {> >int> n = 2;> >cin>> n;> >return> 0;> }> |
>
>
Produksjon
Segementation Fault>
5. Stabeloverløp
Det er ikke et pekerelatert problem, selv om koden ikke har en eneste peker. Det er på grunn av å gå tom for minne på stabelen. Det er også en type minnekorrupsjon som kan skje på grunn av stor matrisestørrelse, et stort antall rekursive anrop, mange lokale variabler, etc.
Eksempel:
C
// C program to illustrate the> // segmentation fault due to> // stack overflow> #include> int> main()> {> >int> arr[2000000000];> >return> 0;> }> |
>
>
C++
// C++ program to illustrate> // the segmentation fault> // due to stack overflow> #include> using> namespace> std;> int> main()> {> >int> array[2000000000];> >return> 0;> }> |
>
>
Produksjon
Segmentation Fault>
6. Bufferoverløp
Hvis dataene som lagres i bufferen er større enn den tildelte størrelsen på bufferen, oppstår et bufferoverløp som fører til segmenteringsfeilen. De fleste metodene i C-språket utfører ikke bundet kontroll, så bufferoverløp skjer ofte når vi glemmer å tildele den nødvendige størrelsen til bufferen.
Eksempel:
C
// C program to illustrate the> // segementation fault due to> // buffer overflow> #include> int> main()> {> >char> ref[20] =>'This is a long string'>;> >char> buf[10];> >sscanf>(ref,>'%s'>, buf);> >return> 0;> }> |
>
>
C++
// C++ program to illustrate the> // segementation fault due to> // buffer overflow> #include> using> namespace> std;> int> main()> {> >char> ref[20] =>'This is a long string'>;> >char> buf[10];> >sscanf>(ref,>'%s'>, buf);> >return> 0;> }> |
>
>
Produksjon
Segmentation Fault>
7. Frareferanse til en uinitialisert eller NULL-peker
Det er en vanlig programmeringsfeil å avreferere en uinitialisert peker ( wild pointer ), som kan resultere i udefinert oppførsel. Når en peker brukes i en kontekst som behandler den som en gyldig peker og får tilgang til dens underliggende verdi, selv om den ikke er initialisert for å peke til en gyldig minneplassering, oppstår denne feilen. Datakorrupsjon, programfeil eller segmenteringsfeil kan skyldes dette. Avhengig av miljøet og tilstanden deres når de refererer, kan ikke-initialiserte pekere gi forskjellige resultater.
Som vi vet, peker ikke NULL-pekeren til noen minneplassering, så det vil resultere i en segmenteringsfeil hvis den frakobles.
Eksempel:
C
// C program to demonstrate segmentation> // fault when uninitialized pointer> // is accessed> #include> int> main()> {> >int>* ptr;> >int>* nptr = NULL;> >printf>(>'%d %d'>, *ptr, *nptr);> >return> 0;> }> |
>
cp kommando i linux
>
C++
// C++ program to demonstrate segmentation> // fault when uninitialized pointer> // is accessed> #include> using> namespace> std;> int> main()> {> >int>* ptr;> >int>* nptr = NULL;> >cout << *ptr <<>' '> << *nptr;> >return> 0;> }> |
>
>
Produksjon
Segmentation Fault>
Hvordan fikse segmenteringsfeil?
Vi kan fikse segmenteringsfeil ved å være forsiktige med årsakene som er nevnt:
- Unngå å endre strengbokstaver.
- Vær forsiktig når du bruker pekere da de er en av de vanligste årsakene.
- Vurdere bufferen og stabelstørrelsen før du lagrer dataene for å unngå buffer- eller stabeloverflyt.
- Se etter grenser før du får tilgang til matriseelementer.
- Bruk scanf() og printf() forsiktig for å unngå feil formatspesifikasjoner eller bufferoverløp.
Totalt sett er årsaken til segmenteringsfeilen tilgang til minnet som ikke tilhører deg i det rommet. Så lenge vi unngår å gjøre det, kan vi unngå segmenteringsfeilen. Hvis du ikke finner kilden til feilen selv etter at du har gjort det, anbefales det å bruke en debugger da den direkte fører til feilpunktet i programmet.