Segmenteringsfel ( eng. Segmentation fault , förkortning segfault , jarg . segfault) är ett programvarufel som uppstår när du försöker komma åt minnesområden som är otillgängliga för skrivning eller när du försöker ändra minne på ett förbjudet sätt. På system baserade på Motorola 68000-processorer är dessa fel allmänt kända som adress- eller bussfel .
På UNIX-liknande operativsystem tar en process som får åtkomst till ogiltigt minne emot SIGSEGV- signalen . På Microsoft Windows kommer en process som får åtkomst till ogiltigt minne att skapa ett STATUS_ACCESS_VIOLATION- undantag (definition för kod 0xC0000005 [1] ) och kommer vanligtvis att uppmana programfelsökaren att köra och visa användaren ett fönster som uppmanar dem att lämna in en felrapport till Microsoft .
Här är ett exempel på ANSI C -kod som resulterar i ett segmenteringsfel på grund av närvaron av en typkvalificerare const :
const char * s = "hej världen" ; * ( char * ) s = 'H' ;När programmet som innehåller denna kod kompileras placeras raden "hello world" i programdelen med en binär skrivskyddad markering. Vid start placerar operativsystemet det, tillsammans med andra strängar och konstanter , i ett skrivskyddat minnessegment. När variabeln har körts pekar den på adressen till början av strängen och ett försök att tilldela värdet på en teckenkonstant genom en variabel i minnet resulterar i ett segmenteringsfel. s 'H'
Att kompilera och köra sådana program på OpenBSD 4.0 ger följande körtidsfel:
$ gcc segfault.c -g -o segfault $ ./segfault Segmenteringsfel Program mottagen signal SIGSEGV, Segmenteringsfel. 0x1c0005c2 i main() vid segfault.c:6 6 *s = 'H';Däremot returnerar GCC 4.1.1 på GNU/Linux ett fel vid kompilering :
$ gcc segfault.c -g -o segfault segfault.c: I funktionen 'main': segfault.c:4: error: tilldelning av skrivskyddad platsFörhållandena under vilka segmenteringsöverträdelser inträffar och hur de yttrar sig beror på operativsystemet .
Detta kodexempel skapar en noll-pekare och försöker tilldela ett värde till en icke-existerande adress. Detta orsakar segmenteringsfel under programkörning på många system .
int * ptr = ( int * ) 0 ; * ptr = 1 ;Ett annat sätt att orsaka ett segmenteringsfel är att anropa funktionen main() rekursivt , vilket kommer att resultera i ett stackspill :
int main () { main (); }Vanligtvis uppstår ett segmenteringsfel eftersom:
Till exempel,
char * p1 = NULL ; /* initierad till null; detta är tillåtet, men på många system kan det inte hänvisas bort */ char * p2 ; /* inte initierad alls (pekar på en godtycklig adress i minnet) */ char * p3 = ( char * ) malloc ( 20 ); /* OK, minne tilldelat */ fri ( p3 ); /* men nu är det borta */Nu kan bortföring av någon av dessa pekare orsaka ett segmenteringsfel.
Eller när du använder arrayer , om du av misstag anger en oinitierad variabel som storleken på en array :
int main () { const int nmax = 10 ; int i , n , a [ n ]; }G++- kompilatorn spårar inte detta länkningsfel , vilket kan orsaka ett segmenteringsfel när det kompilerade programmet körs .
av operativsystem | Aspekter|||||
---|---|---|---|---|---|
| |||||
Typer |
| ||||
Kärna |
| ||||
Processledning _ |
| ||||
Minneshantering och adressering | |||||
Ladda och initieringsverktyg | |||||
skal | |||||
Övrig | |||||
Kategori Wikimedia Commons Wikibooks Wiktionary |