Question

J'ai un vecteur que je charge avec une quantité connue d’éléments (N).

Le traitement crée dynamiquement de nouveaux éléments, qui sont ajoutés au vecteur.

J'attends environ 2 * N éléments supplémentaires, donc je redimensionne le vecteur à 3 * N.

Si les éléments supplémentaires dépassent cette limite, j'aimerais un programme abandonné plutôt qu'un développement dynamique du vecteur.

Existe-t-il un moyen de détecter ce problème, qu'il soit portable entre AIX / TRU64 / Linux?

Était-ce utile?

La solution

Détecter quoi? Si le vecteur sera redimensionné? Si cela a été?

Le seul moyen d'y parvenir consiste à fournir une fonctionnalité de vérification dans un allocateur personnalisé ou une fonction qui ajoute des éléments au vecteur.

exemple

template<class T> 
void add_element(std::vector<T>& container, T const& v)
{
  if (container.capacity()+1 >= 3*N)
  {
    // terminate/exception/whatever
  }

 container.push_back(v);
}

Autres conseils

Pourquoi utilisez-vous un vecteur? Le but du vecteur est de se développer dynamiquement si nécessaire.

Au lieu de faire déléguer une classe au vecteur, créez simplement une classe à déléguer à un tableau simple. Demandez à votre push_back de vérifier la taille et d’abandonner au besoin.

Créez votre propre classe qui déléguera au vecteur. Et vérifiez la taille dans votre propre push_back.

Si vous connaissez la taille au moment de la compilation, utilisez peut-être un std :: tr1 :: array (ou boost :: array ) serait un meilleur choix. Il garde une taille fixe et vérifie l’accès comme std :: vector.

Si toutefois vous ne le connaissez qu'au moment de l'exécution, comme indiqué par d'autres ici, vous devez encapsuler votre vecteur dans une classe avec des fonctions spécifiques qui vérifieront les conditions souhaitées (via des assertions, par exemple).

Dans cette dernière approche, je vous suggère, si vous pouvez connaître la taille maximale lors de la création du vecteur, de réserver (std :: vector :: reserve ()) la taille maximale du vecteur dans le constructeur de votre classe d'encapsulation (ou fonction d'initialisation). De cette façon, il n'y aura plus de manipulations de mémoire par le vecteur lui-même (uniquement si le constructeur / destructeur des éléments de vecteurs effectue de telles manipulations). Ensuite, l'ajout d'une assertion simple vérifiant que la capacité vectorielle (std :: vector :: capacity ()) n'a jamais changé au début et à la fin de toutes les fonctions de votre classe vous aidera à vous assurer que sa mémoire ne se déplace pas.

Par exemple (en supposant que DATA_MAX_SIZE est une taille maximale par défaut définie quelque part):

template< typename MyType >
class MyData
{
public:
    MyData( unsigned long max_size = DATA_MAX_SIZE )
        : m_max_size( max_size )
        { m_data.reserve( m_max_size ); }

    void add( const MyType& value ) { check_capacity(); m_data.push_back( value ); check_capacity(); }



private:

    std::vector< MyType > m_data;
    const unsigned long m_max_size;

    void check_capacity() { if( m_data.capacity() != m_max_size ) throw Exception("Useful error message here!" ); }

};

Ou quelque chose comme ça ...

Les classes std utilisent un allocateur appelé à chaque fois que vous insérez un élément. Vous pouvez écrire un nouvel allocateur héritant de std :: alocator et ajouter toutes sortes de vérifications / traces dont vous avez besoin.

(Je l'avais déjà fait auparavant, mais il m'a fallu un certain temps pour créer du code fonctionnel.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top