Comment détecter si une erreur de segment non initialisée / catch variable en C

J’ai actuellement un programme dans lequel j’ai besoin de tester si une variable passée en paramètre est non initialisée. Jusqu’ici, il semble que cela soit assez difficile à faire en C, donc mon idée suivante était d’invoquer un gestionnaire de signal pour intercepter l’erreur de segmentation. Cependant, mon code n’appelle pas le gestionnaire de signal lorsqu’il tente d’accéder à la variable non initialisée, comme suit:

void segfault_sigaction(int signal, siginfo_t *si, void *arg) { printf("Caught segfault at address %p\n", si->si_addr); exit(0); } void myfree(void*p, char * file, int line){ struct sigaction sa; memset(&sa, 0, sizeof(sigaction)); sigemptyset(&sa.sa_mask); sa.sa_sigaction = segfault_sigaction; sa.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &sa, NULL); char up = *((char*)p); //Segfault 

EDIT: sur le système Linux

Ce n’est pas une bonne idée. Si le programme tente d’utiliser une variable non initialisée, il s’agit toujours d’un bogue. La bonne façon de trouver ce bogue est d’utiliser un bon compilateur avec tous les avertissements activés ou, mieux encore, un outil d’parsing statique. Le bogue devrait être trouvé et corrigé lorsque le programme est développé. Pas en cours d’exécution.

De plus, avec une bonne conception du programme, l’appelant est responsable de la transmission des parameters corrects à une fonction. La fonction ne devrait pas avoir à se préoccuper de l’appelant. Si un paramètre incorrect est passé par référence, tous les paris sont désactivés.

L’access à la mémoire pointée par un pointeur non initialisé entraîne un comportement indéfini, ce qui inclut les résultats suivants:

  • Il y a une faute de segmentation.
  • Il y a un crash de programme.
  • Rien ne se passe mais le programme commence à se comporter de manière étrange.
  • Rien ne se passe et le programme semble bien fonctionner.

Si vous faites cela parce que vous voulez une programmation défensive, vous devriez plutôt envisager une sorte de vérification de l’intégrité des valeurs de variable, de préférence via assert () ou static_assert ().

Essayez d’utiliser Valgrind avec l’outil memcheck. Il peut détecter les access non initialisés à la mémoire, ainsi que plusieurs autres types d’access non valides. Un tutoriel peut être trouvé ici . L’ajout de l’argument –track-origins = yes (nécessite la version 3.4.0) peut faciliter la recherche d’utilisations de la mémoire non initialisée.

Les pointeurs n’ont pas de valeur par défaut si vous ne l’avez pas initialisé. Parfois, c’est NULL (si p est NULL , vous pouvez attraper le SIGSEGV ), parfois, il pointe vers une mémoire valide et semble que tout va bien. La valeur qu’ils ont est tout ce que la malbouffe était dans la mémoire qu’ils utilisent maintenant. En ce qui concerne votre problème, je suggérerais d’écrire votre propre version de malloc() et de free() , de mettre un nombre magique dans l’en-tête de la mémoire allouée et de vérifier si elle est toujours là lors de la libération.