logo

Segmenteringsfejl i C/C++

Segmenteringsfejl i C eller C++ er en fejl, der opstår, når et program forsøger at få adgang til en hukommelsesplacering, det ikke har tilladelse til at få adgang til. Generelt opstår denne fejl, når hukommelsesadgang krænkes og er en type generel beskyttelsesfejl. Segfaults er forkortelsen for segmenteringsfejl.

Det kernedump refererer til registreringen af ​​programmets tilstand, dvs. dets ressourcer i hukommelse og processor. At forsøge at få adgang til ikke-eksisterende hukommelse eller hukommelse, som bruges af andre processer, forårsager også segmenteringsfejlen, som fører til et kernedump.



Et program har adgang til bestemte områder af hukommelsen, mens det kører. Først bruges stakken til at holde de lokale variabler for hver funktion. Desuden kan den have hukommelse allokeret under kørsel og gemt på heapen (ny i C++, og du kan også høre det kaldet gratis butik ). Den eneste hukommelse, som programmet har tilladelse til at få adgang til, er dens egen (den tidligere nævnte hukommelse). En segmenteringsfejl vil skyldes enhver adgang uden for det pågældende område.

Segmenteringsfejl er en specifik form for fejl forårsaget af adgang til hukommelse tilhører ikke dig :

  • Når et stykke kode forsøger at udføre en læse-og-skrive-operation på en skrivebeskyttet placering i hukommelsen eller frigjort hukommelsesblok, er det kendt som en segmenteringsfejl.
  • Det er en fejl, der indikerer hukommelseskorruption.

Almindelige segmenteringsfejlscenarier

I en segmenteringsfejl forsøger et program at få adgang til hukommelse, der ikke er autoriseret til at få adgang til, eller som ikke eksisterer. Nogle almindelige scenarier, der kan forårsage segmenteringsfejl, er:



  1. Ændring af en streng bogstavelig
  2. Adgang til en adresse, der er frigivet
  3. Adgang til out-of-array indeksgrænser
  4. Ukorrekt brug af scanf()
  5. Stack Overflow
  6. Derhenviser ikke-initialiseret markør

1. Ændring af en streng literal

Strengliteralerne gemmes i den skrivebeskyttede sektion af hukommelsen. Det er grunden til, at nedenstående program kan gå ned (giver segmenteringsfejl), fordi linjen *(str+1) = 'n' forsøger at skrive en skrivebeskyttet hukommelse.

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;> }>

>

>

Produktion

timeout: den overvågede kommando dumpede kerne

/bin/bash: linje 1: 32 Segmenteringsfejl timeout 15s ./83b16132-8565-4cb1-aedb-4eb593442235 <83b16132-8565-4cb1-aedb-4eb593442235.

Se Lagring til strenge i C for flere detaljer.

2. Adgang til en adresse, der er frigivet

Her i nedenstående kode er pointeren p dereferenceret efter frigørelse af hukommelsesblokken, hvilket ikke er tilladt af compileren. Sådanne pointere kaldes dinglende pointere, og de producerer segmentfejl eller unormal programafslutning under kørsel.

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øgetræ

>

>

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;> }>

>

>

Produktion

Segmentation Fault>

3. Adgang til out-of-bounds Array Index

I C og C++ kan adgang til et out-of-bounds array-indeks forårsage en segmenteringsfejl eller anden udefineret adfærd. Der er ingen grænsekontrol for arrays i C og C++. Selvom det er i C++, kan brugen af ​​containere, såsom med std::vector::at()-metoden eller med en if()-sætning, forhindre out-of-bound fejl.

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;> }>

>

>

Produktion

Segmentation Faults>

4. Ukorrekt brug af scanf()

Funktionen scanf() forventer adressen på en variabel som input. Her i dette program tager n værdien 2 og antager sin adresse som 1000. Hvis vi sender n til scanf(), bliver input hentet fra STDIN placeret i ugyldig hukommelse 2, som i stedet burde være 1000. Dette forårsager hukommelseskorruption, hvilket fører til en segmenteringsfejl.

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;> }>

>

>

Produktion

Segementation Fault>

5. Stakoverløb

Det er ikke et pointerelateret problem, selv kode har muligvis ikke en enkelt pointer. Det er på grund af at løbe tør for hukommelse på stakken. Det er også en form for hukommelseskorruption, der kan ske på grund af stor matrixstørrelse, et stort antal rekursive opkald, masser af lokale variabler osv.

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;> }>

>

>

Produktion

Segmentation Fault>

6. Bufferoverløb

Hvis dataene, der lagres i bufferen, er større end den tildelte størrelse af bufferen, opstår der et bufferoverløb, som fører til segmenteringsfejlen. De fleste af metoderne i C-sproget udfører ikke bundet kontrol, så bufferoverløb sker ofte, når vi glemmer at tildele bufferen den nødvendige størrelse.

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;> }>

>

>

Produktion

Segmentation Fault>

7. Frareference af en ikke-initialiseret eller NULL-markør

Det er en almindelig programmeringsfejl at dereferere en ikke-initialiseret pointer (wild pointer), som kan resultere i udefineret adfærd. Når en pointer bruges i en kontekst, der behandler den som en gyldig pointer og får adgang til dens underliggende værdi, selvom den ikke er blevet initialiseret til at pege på en gyldig hukommelsesplacering, opstår denne fejl. Datakorruption, programfejl eller segmenteringsfejl kan skyldes dette. Afhængigt af deres miljø og tilstand, når de refererer, kan ikke-initialiserede pointere give forskellige resultater.

Som vi ved, peger NULL-markøren ikke på nogen hukommelsesplacering, så at dereferencere den vil resultere i en segmenteringsfejl.

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;> }>

>

>

Produktion

Segmentation Fault>

Hvordan rettes segmenteringsfejl?

Vi kan rette segmenteringsfejl ved at være forsigtige med de nævnte årsager:

  • Undgå at ændre strenge bogstaver.
  • Vær forsigtig, når du bruger pointere, da de er en af ​​de mest almindelige årsager.
  • Overvej buffer og stakstørrelse før lagring af data for at undgå buffer eller stak overløb.
  • Kontrollerer for grænser, før du får adgang til matrixelementer.
  • Brug scanf() og printf() forsigtigt for at undgå forkerte formatspecifikationer eller bufferoverløb.

Overordnet set er årsagen til segmenteringsfejlen adgang til den hukommelse, der ikke tilhører dig i det pågældende rum. Så længe vi undgår at gøre det, kan vi undgå segmenteringsfejlen. Hvis du ikke kan finde kilden til fejlen selv efter at have gjort det, anbefales det at bruge en debugger, da det direkte fører til fejlpunktet i programmet.