Segmentointi vika (in Englanti segmentointi vika , lyhennettynä segfault ) on kaatua olevan sovelluksen , joka yrittänyt käyttää paikkaan muistia , joka ei myönnetty.
Käynnissä olevat sovellukset tarvitsevat käyttöjärjestelmän varaamaa RAM-muistia . Kun se on osoitettu sovellukselle, mikään muu sovellus ei voi käyttää tätä aluetta; Tämä takaa toiminnallinen luotettavuus kullekin sovellukselle vastaan virheitä muiden. Siten, jos sovellus yrittää pienintäkään pääsyä muistialueelle, jota ei ole varattu sille, käyttöjärjestelmä tunnistaa sen ja lopettaa välittömästi sen suorittamisen.
Suurin osa segmentointivirheistä ei ole tahallisia (jos on, on hyvät mahdollisuudet, että se on rikollista tarkoitusta varten); ne johtuvat sovelluksen huonosta suunnittelusta tai toteutuksesta.
Kun ohjelma suoritetaan, käyttöjärjestelmä allokoi sille muistin. Mutta sattuu, että suorituksen aikana sovellus tarvitsee lisämuistia prosessointitarpeisiinsa. Sitten se pyytää käyttöjärjestelmää varaamaan sille tietyn määrän muistia. Sitten sovelluksen vastuulla on käyttää tätä muistia ja olla varovainen, ettet kirjoita tai lue varatun muistialueen ulkopuolella.
Koko ongelma on tietää missä olet, kun käytät tätä muistia. Ja silloin kun emme huolehdi, liikaa muistiamme ja sovellus päättyy. Tätä kutsutaan puskurin ylivuotoksi .
Toinen segmentointivirheiden syy on huono osoittimen alustus . Jälkimmäinen osoittaa sitten mille tahansa muistialueelle ja kun sitä käytetään, on hyvä mahdollisuus, että jälkimmäinen sisältää osoitteen, jota ei ole varattu sovellukselle. Ja kuten aiemmin, käyttöjärjestelmä tuottaa segmentointivirheen.
Osoittimien ongelmien välttämiseksi on tarpeen alustaa ne kelvollisella osoitteella tai NULL- koodiin (koodin on käsiteltävä se oikein) ennen käyttöä.
Tässä on esimerkkejä C- ohjelmista, jotka voivat tuottaa tällaisen virheen.
Scanf toiminto pyrkii hakea kokonaisluku vakiosyötteestä (oletuksena näppäimistö ) ja tallentaa tämän arvon muuttujaan . Tietojen tallentamiseksi siellä scanf: n on tiedettävä muuttujan osoite (meidän tapauksessamme: variable_entiere).
Meidän tapauksessamme arvoa variable_entiereei kuitenkaan alusteta, joten sillä on mitään arvoa. Scanf- toiminto yrittää sitten päästä muistialueelle, jota edustaa arvon sisältämä arvo, variable_entiereja todennäköisesti aiheuttaa segmentointivirheen.
Ongelmana on, että haluamme tallentaa toiminnan tuloksen valeur * valeurja käyttää sitä osoittimella (nimetty tässä pointeur). Koska osoitin ei kuitenkaan allokoi muuta muistitilaa kuin itselleen, sille ei voida antaa arvoa ennen kuin se osoittaa oikein varattua muistitilaa (kuten muuttujaa) vaarantamatta segmentointivirhettä. Koska alustamaton osoitin osoittaa satunnaiselle paikalle muistissa.
Yksi ratkaisu on luoda toinen muuttuja (nimetty tässä resultat), johon osoitin osoittaa:
int main() { int *pointeur, valeur, resultat; pointeur = &resultat; valeur = 3; *pointeur = valeur * valeur; /* maintenant la variable resultat contient 9 */ return (EXIT_SUCCESS); }Toinen ratkaisu olisi dynaaminen muistin allokointi, ts. Käyttöjärjestelmän muistin pyytäminen ja osoittimen osoittaminen uudelle muistitilalle:
#include <stdlib.h> int main() { int *pointeur, valeur; pointeur = malloc(sizeof(*pointeur)); if (pointeur == NULL) /* La fonction malloc() retourne NULL en cas d'échec. */ return (EXIT_FAILURE); valeur = 3; *pointeur = valeur * valeur; free(pointeur); /* On libère la mémoire. */ return (EXIT_SUCCESS); }Segmenttivirheen aikana kuoren antama virhe on 139 : prosessin loppu johtuu signaalista, kuori lisää 128signaalin koodiin. SIGSEGVkelvollinen 11, vastaanotettu virhe on 139.