8
votes

Envelopper une matrice dynamique dans le conteneur STL / BOOST?

J'ai besoin d'envelopper un tableau alloué de manière dynamique (d'un nouveau double [100] par exemple) dans std :: vecteur (de préférence) sans copier le tableau. Cette restriction est imposée par que la matrice que je veux envelopper est mmaped à partir d'un fichier, alors faites simplement un vecteur (A, une taille) doublera l'utilisation de la mémoire.

est des astuces pour faire ça?


1 commentaires

Quoi qu'il en soit, vous n'obtiendrez pas d'ensemble de capacités de std :: Vecteur (par exemple (E.G. Redimensionnez-vous, probablement ne fonctionnera pas), peut-être que ce serait bien de répertorier ce dont vous avez besoin exactement de Wrapper?


8 Réponses :


1
votes

Non, ce n'est pas possible à l'aide d'un std :: vecteur code>.

Mais si possible, vous pouvez créer le vecteur avec cette taille et mapper le fichier possible à cela. P >

std::vector<double> v(100);
mmapfile_double(&v[0], 100);


0 commentaires

1
votes

Qu'en est-il du vecteur des pointeurs qui pointent sur vos éléments de zone mappés (consommation de mémoire réduite comme taille de taille (double *)

Il y a des inconvénients (primaire est que vous avez besoin de prédicats spéciaux pour TRY), mais des avantages aussi que possible, par exemple, supprimer des éléments sans modifier le contenu mappé réel (ou même un nombre de ces tableaux avec un ordre d'ordre différent sans aucune changer les valeurs réelles).

Il y a un problème courant de toutes les solutions avec STD :: Vector sur le fichier mappé: sur le contenu du vecteur "ongle" à la zone mappée. Cela ne peut pas être suivi, vous ne pouvez regarder que vous pouvez regarder vous-même de ne pas utiliser quelque chose qui pourrait conduire à la réaffectation de contenu de vecteur. Alors soyez prudent dans tous les cas.


0 commentaires

2
votes

J'étais déjà déterminé à accomplir exactement la même chose. Après quelques jours de pensée et essayant, j'ai décidé que cela n'allait pas la peine. J'ai fini par créer mon propre vecteur personnalisé qui s'est comporté comme STD :: vecteur, mais seulement la fonctionnalité que je n'avait réellement besoin que comme une vérification liée, des itérateurs, etc.

Si vous désirez toujours utiliser STD :: Vector, la seule façon dont je pouvais penser à l'arrière puis à créer un allocator personnalisé. Je n'ai jamais écrit un mais voyant comme il s'agit du seul moyen de contrôler la gestion de la mémoire de la STL peut-être quelque chose qui peut être fait là-bas.


2 commentaires

Je suggère de ne pas écrire un propre conteneur. La plupart du temps ne valent tout simplement pas la peine et conduit à des problèmes d'interopératibilité assez nombreux. De plus, le temps passé au débogage des trucs réinventés est gaspillé du temps. L'allocator personnalisé est toutefois très facile à mettre en œuvre et à une meilleure approche.


Normalement, je serais d'accord, mais je pense vraiment que cela dépend de ce que vous allez faire avec cela. La plupart des opérations "complexes" dans STD :: Vector ont probablement quelque chose à voir avec la gestion de la mémoire et il arrive que dans ce cas, aucun d'entre eux n'est requis. Donc, écrire une petite classe avec vérification des limites et un pointeur comme un itérateur ne devrait pas prendre trop de temps. Je ne peux pas commenter l'interopérabilité depuis que je n'ai aucune connaissance d'où / comment l'auteur a l'intention de l'utiliser. Mais le support d'itérateur devrait le faire fonctionner avec les algorithmes de STL.



11
votes

L'une des meilleures solutions pour cela est quelque chose comme stlsoft's Array_Proxy modèle. Malheureusement, la page DOC générée par le code source par Doxygen n'est pas beaucoup d'aide à comprendre le modèle. Le code source pourrait réellement être un peu mieux:

  • http://www.stlsoft.org/doc-1.9 /array__proxy_8hpp-source.html code> LI> ul>

    Le modèle array_proxy code> est décrit bien dans Le livre de Matthew Wilson, imparfait C ++ . La version que j'ai utilisée est une version coupée de ce qui est sur le site de STLSoft, donc je n'avais pas à tirer dans toute la bibliothèque. Ma version n'est pas aussi portable, mais cela rend beaucoup plus simple que ce qui se trouve sur STLSoft (qui saute à travers un grand nombre de cerceaux de portabilité). P>

    Si vous configurez une variable comme: P>

    int myArray[100];
    
    array_proxy<int> myArrayProx( myArray);
    


1 commentaires

+1, semble être la meilleure solution, en particulier parce que le proxy ne doit pas réaffecter la mémoire, il devrait donc être exempt de nombreux problèmes.



1
votes

Vous pouvez aller avec Array_Proxy <> ou jeter un coup d'œil à Boost.Array . Il vous donne une taille (), avant (), arrière (), à (), opérateur [], etc. Personnellement, je préférerais Boost.Array puisque Boost est plus répandu de toute façon.


0 commentaires


1
votes

Eh bien, le modèle de vecteur permet de fournir votre propre allocateur de mémoire. Je ne l'ai jamais fait moi-même, mais je suppose que ce n'est pas si difficile de l'obtenir de pointer vers votre tableau, peut-être avec un nouvel opérateur de placement ... Juste une supposition, j'écris plus si j'essaie de réussir.


0 commentaires

0
votes

Voici la solution à votre question. J'y essayais depuis un certain temps avant de trouver une solution réalisable. La mise en garde est que vous devez avoir à zéro les pointeurs après utilisation afin d'éviter de doubler la mémoire de la mémoire.

template <class T>
class vectorWrapper : public std::vector<T>
{   
public:
  vectorWrapper() {
    this->_M_impl _M_start = this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = NULL;
  }   

  vectorWrapper(T* sourceArray, int arraySize)
  {   
    this->_M_impl _M_start = sourceArray;
    this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = sourceArray + arraySize;
  }   

  ~vectorWrapper() {
    this->_M_impl _M_start = this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = NULL;
  }   

  void wrapArray(T* sourceArray, int arraySize)
  {   
    this->_M_impl _M_start = sourceArray;
    this->_M_impl _M_finish = this->_M_impl _M_end_of_storage = sourceArray + arraySize;
  }   
};  


0 commentaires