2009-03-01 4 views
0

J'ai un vecteur que je charge avec un certain nombre d'éléments (N).redimensionnement de vecteur - façon portable de détecter

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

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

Si les éléments supplémentaires dépassent, je voudrais un programme abandonner, plutôt que d'une dynamique l'expansion du vecteur.

Existe-t-il un moyen de détecter cela, c'est-à-dire portable entre AIX/TRU64/Linux?

Répondre

3

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

La seule façon d'y parvenir est de fournir une fonctionnalité de vérification dans un allocateur personnalisé ou une fonction qui ajoute des éléments au vecteur.

par 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); 
} 

2

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

2

Si vous connaissez la taille au moment de la compilation, peut-être utiliser 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 dit ici, vous devez encapsuler votre vecteur dans une classe avec des fonctions spécifiques qui vérifient les conditions que vous voulez (via des assertions par exemple). Dans cette dernière approche, je suggère, si vous pouvez connaître la taille maximale à la création du vecteur, de réserver (std :: vector :: reserve()) la taille maximale du vecteur dans votre constructeur de classe d'encapsulation (ou fonction d'initialisation). De cette façon, il n'y aura plus de manipulations de la mémoire par le vecteur lui-même (seulement si le constructeur/destructeur d'éléments vectoriels fait de telles manipulations). Ensuite, ajouter une assertion simple qui vérifie que la capacité du vecteur (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 bouge pas.

Par exemple (en supposant 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 ...

3

Pourquoi utilisez-vous un vecteur? Le point entier du vecteur est de développer dynamiquement en cas de besoin. Au lieu de créer une classe à déléguer au vecteur, faites simplement une classe à déléguer à un simple tableau. Avoir votre push_back vérifier la taille et abandonner si nécessaire.

2

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 les vérifications/traces dont vous avez besoin.

(Je l'ai fait avant, mais il m'a fallu un certain temps pour faire du code de travail.

+1

l'allocateur n'est pas nécessairement appelé à chaque fois, le vecteur ne l'utilisera que lorsqu'il a besoin d'augmenter la capacité, pas la taille –

Questions connexes