web-dev-qa-db-fra.com

Qu'est-ce qu'une erreur d'exécution SIGSEGV en C++?

J'ai besoin de connaître la cause première de l'erreur de segmentation, et quelqu'un peut-il me dire comment le gérer?.

25
Vaibhav

Wikipedia a la réponse, ainsi que plusieurs autres sources.

Une erreur de segmentation signifie fondamentalement que vous avez fait quelque chose de mal avec des pointeurs. C'est probablement une erreur de segmentation:

char *c = NULL;
...
*c; // dereferencing a NULL pointer

Ou ca:

char *c = "Hello";
...
c[10] = 'z'; // out of bounds, or in this case, writing into read-only memory

Ou peut-être ceci:

char *c = new char[10];
...
delete [] c;
...
c[2] = 'z'; // accessing freed memory

Même principe de base dans chaque cas - vous faites quelque chose avec une mémoire qui n'est pas la vôtre.

45
Chris Lutz

Les erreurs de segmentation peuvent avoir différentes causes mais, fondamentalement, vous n’accédez pas correctement à la mémoire. Cela peut être dû au déréférencement d'un pointeur null, à une tentative de modification de la mémoire en lecture seule ou à l'utilisation d'un pointeur vers un endroit non mappé dans l'espace mémoire de votre processus (cela signifie probablement que vous essayez d'utiliser un nombre comme pointeur). , ou vous avez incrémenté un pointeur trop loin). Sur certaines machines, il est également possible qu’un accès mal aligné par un pointeur pose le problème - si vous avez une adresse étrange et essayez de lire un nombre pair d’octets, par exemple (qui peut générer SIGBUS à la place).

11
Jonathan Leffler

en utilisant un pointeur invalide/nul? Dépasser les limites d'un tableau? Kindof difficile d'être spécifique sans aucun code exemple.

Essentiellement, vous essayez d'accéder à de la mémoire qui n'appartient pas à votre programme, alors le système d'exploitation la tue.

4
MichaelM

Voici un exemple de SIGSEGV.

root@pierr-desktop:/opt/playGround# cat test.c
int main()
{
     int * p ;
     * p = 0x1234;
     return 0 ;
}
root@pierr-desktop:/opt/playGround# g++ -o test test.c  
root@pierr-desktop:/opt/playGround# ./test 
Segmentation fault

Et voici le détail .

Comment le gérer?

  1. Évitez-le le plus possible en première place.

    Programmez de manière défensive: utilisez assert (), vérifiez le pointeur NULL, vérifiez le dépassement de tampon.

    Utilisez des outils d'analyse statique pour examiner votre code.

    compilez votre code avec -Werror -Wall.

    Est-ce que quelqu'un a révisé votre code?.

  2. Quand cela s'est réellement passé.

    Examinez attentivement le code. 

    Vérifiez ce que vous avez changé depuis la dernière fois que votre code a été exécuté avec succès sans crash.

    Espérons que gdb vous fournira une pile d’appels afin que vous sachiez où le crash s’est produit.


EDIT: désolé pour une précipitation. Il devrait être *p = 0x1234; au lieu de p = 0x1234

4
pierrotlefou

l'erreur de segmentation survient lorsque vous accédez à une mémoire non déclarée par le programme. Vous pouvez le faire via des pointeurs, c.-à-d. Des adresses de mémoire. Cela peut aussi être dû au stackoverflow pour par exemple: 

void rec_func() {int q = 5; rec_func();}

int main() {rec_func();}

Cet appel continuera à consommer de la mémoire de pile jusqu’à ce qu’elle soit complètement remplie et donc finalement à produire un débordement de pile ... mal à comprendre sigsemv. 

0
NIKESH SINGH