2009-05-22 5 views
2

Comment saisir une mauvaise référence de tableau en C++? Pourquoi pas le travail de code suivant:Saisir une mauvaise référence de tableau en C++

#include <exception> 

    int * problemNum = new int; 
    int (* p [100])() = {problem1, problem2, problem3}; 

    ... 

    try { 
     cout << (*p[*problemNum-1])(); 
    } 
    catch (exception){ 
     cout << "No such problem"; 
    } 

Mon compilateur dit: exception non gérée à 0xcccccccc en Euler.exe: 0xC0000005: violation d'accès. lorsque j'initie une mauvaise référence en entrant 0 comme * numéroDeNuméro.

Répondre

3

Becauce C++ ne peut pas gérer de telles erreurs avec son mécanisme d'exception. Voir Defective C++ sur ce problème.

Utilisez sigaction(2).

sigaction - examiner et modifier une action de signal

SYNOPSIS

#include <signal.h> 

    int sigaction(int signum, const struct sigaction *act, 
       struct sigaction *oldact); 

DESCRIPTION L'appel système sigaction() est utilisée pour modifier l'action effectuée par un procédé de réception d'un spécifique signal. Signum spécifie le signal et peut être n'importe quel signal valide sauf SIGKILL et SIGSTOP. Si act est non nul, la nouvelle action pour signum de signal est installée à partir de act. Si oldact est non nul, l'action précédente est enregistrée dans oldact. La structure sigaction est définie comme quelque chose comme:

 struct sigaction { 
      void  (*sa_handler)(int); 
      void  (*sa_sigaction)(int, siginfo_t *, void *); 
      sigset_t sa_mask; 
      int  sa_flags; 
      void  (*sa_restorer)(void); 
     }; 

Vous devez attraper SIGSEGV, vous pouvez joindre votre propre gestionnaire (fonction qui est appelée lorsque l'accès à la mémoire illégale est effectuée).

+0

Vous ne voulez vraiment pas commencer à attraper SIGSEGV dans ce cas. Il est absolument faux d'utiliser des fautes de segmentation comme vérification de limite de tableau. Mieux vaut juste utiliser std :: vector. – sth

4

alamar a raison - C++ n'acceptera pas d'exceptions avec ce type de tableau.

Utilisez un vecteur STL à la place:

#include <exception> 
#include <vector> 

int * problemNum = new int; 
std::vector<int(*)()> p; 
p.push_back(problem1); 
p.push_back(problem2); 
p.push_back(problem3); 

... 

try { 
    cout << p.at(*problemNum-1)(); 
} 
catch (exception){ 
    cout << "No such problem"; 
} 
+2

Cela ne déclenchera pas non plus d'exception. Si vous avez besoin d'une exception lors de l'accès à un élément en dehors des limites, utilisez la fonction membre "at" et non l'opérateur bracket. –

+0

Dang tu as raison Rob, je n'ai jamais su ça! Je vais changer l'exemple de code. –

Questions connexes