2010-04-17 11 views
2
int arr[ 5 ] = { 0 }; 

int i = 8; // out of bounds 

arr[ i ] = 8; 

Je sais que je peux vérifier i like this if (i < 0 || i> 5) ....Comment protéger le code des accidents dans cette situation

Je sais aussi de SEH dans Visual Studio, mais il semble que la solution ne fonctionne pas.

__try { /* code */ } 

__except(GetExceptionCode() == EXCEPTION_ARRAY_BOUNDS_EXCEEDED) 

Cela ne fonctionne pas. Comme je vois SEH travailler dans des situations comme diviser à 0, accéder aux pages protégées ... Comment puis-je protéger mon programme contre les plantages?

Répondre

4

Il n'y a aucune garantie que SEH va attraper ceci - cela dépend de votre matériel détectant l'accès, ce qui ne se produit pas pour tous les accès de matrice non valides. Si vous voulez être sûr de l'attraper, utilisez le conteneur standard C++ std::vector au lieu d'un tableau et accédez-y via sa fonction membre at(), plutôt que l'opérateur []. Cela déclenchera une exception C++ standard si l'accès n'est pas valide.

+0

Bonjour Neil Butterworth. Je connais les conteneurs et je l'utilise quand c'est possible, mais que faire quand j'ai besoin de tableaux? –

+2

@David Comme je l'ai dit dans mon autre commentaire, vous n'avez probablement pas besoin d'utiliser des tableaux - je ne les utilise presque jamais dans mon propre code. Mais si vous sentez que vous en avez besoin, il n'existe aucun moyen garanti de vérifier les violations d'accès. –

+0

Can Valgrind peut-il détecter l'accès hors limites? – fredoverflow

1

Utilisez des conteneurs appropriés comme std :: vector et attraper les exceptions?

+0

Je connais les conteneurs et je les utilise lorsque c'est possible, mais que faire lorsque j'ai besoin de tableaux? –

2

Vous ne pouvez pas vous protéger de cela. Si vous le souhaitez, vous devez utiliser une autre langue qui vérifie pour vous. C et C++ exigent que vous vérifiez vous-même que vous écrivez du code sûr.

Une alternative peut être d'envelopper le tableau dans une struct ...

template<typename E, std::size_t s> 
struct array { 
    E &operator[](std::ptrdiff_t i) { 
    assert(i < s && "out of range!"); 
    return d[i]; 
    } 
    E const &operator[](std::ptrdiff_t i) const { 
    assert(i < s && "out of range!"); 
    return d[i]; 
    } 

    typedef E underlying_array[s]; 
    underlying_array &raw() { return d; } 
    underlying_array const &raw() const { return d; } 

    E d[s]; 
}; 


array<int, 5> arr = { 0 }; 
arr[8] = 8; /* assert will ring */ 
foo(arr.raw()); /* pass as an int[5] */ 

Cette classe est fourni par boost et C++ 0x aussi (mais sans fonction raw), mais la vérification des erreurs est pas nécessaire pour eux.

0

Vous avez deux options:

  • ne pas utiliser des tableaux bruts (utilisation std :: vecteur ou boost :: tableau au lieu)
  • ne pas utiliser C++

la seule autre option est d'écrire le code que ne contient aucune erreur hors-limites

Il n'y a absolument aucun moyen de détecter de manière fiable hors de bou Erreurs nds sur les tableaux bruts en C++.

Vous pourriez juste attraper la violation d'accès que parfois se produit, mais cela ne vous donnera pas un programme correct. Vous allez toujours sortir des limites dans de nombreux autres cas, en écrasant la mémoire allouée précédemment et en corrompant d'autres parties de votre programme.

Questions connexes