1
votes

Comment ajouter des données char à un std :: vector sans provoquer de copie

J'ai un vecteur de caractères qui contient des éléments de données.

unsigned char * data_2;

J'ai un caractère non signé * qui pointe vers un autre ensemble d'éléments de données.

std::vector<unsigned char> data_1;


0 commentaires

4 Réponses :


2
votes

Non, vous ne pouvez pas faire ça.

  • Les données vectorielles sont stockées de manière contiguë, donc à moins que vos tampons ne soient déjà dos à dos (ce qui n'est pas le cas), au moins l'un d'entre eux doit être déplacé (lire: copié)

  • Les vecteurs ne peuvent pas s'approprier la mémoire existante (votre caractère non signé * data_2 )

  • Les vecteurs ne peuvent pas posséder deux blocs de mémoire simultanément (un hypothétique std :: vector data_2 )

Vous pouvez cependant, au moment de l'utilisation, faire en sorte que cela n'a pas d'importance en ayant un seul itérateur de type" saut "du premier tampon au second, de manière transparente .


2 commentaires

Merci pour la réponse rapide. Ce ne serait pas possible même si data_2 était un std :: vector ? Je sais que ce n'est toujours pas possible mais je souhaite confirmer une fois.


@AdeleGoldberg: Non (bien qu'au moins le deuxième point ne soit pas [directement] applicable)



1
votes

Non. Les vecteurs sont stockés de manière contiguë; bien que vous puissiez éviter la réallocation de data_1 en réserver suffisamment d'espace pour la taille complète des données concaténées avant de remplir data_1 , vous ne pouvez pas éviter la copie réelle des octets; les données doivent être déplacées vers une position contiguë aux données existantes dans data_1 , et un vecteur ne peut pas éviter cela.


0 commentaires

5
votes

Est-il possible de fusionner data_2 dans data_1 qui est un vecteur sans provoquer de copie des éléments de données?

Non. Toutes les manières d'insérer des éléments dans un vecteur nécessitent de copier (ou de déplacer) chaque élément au moins une fois.

J'ai lu que la sémantique de déplacement était mentionnée dans cette discussion, mais je ne sais pas si c'est possible dans cette situation que j'ai ici.

Déplacer un caractère équivaut à copier un caractère. La distinction n'est pertinente que pour les types de classe avec un constructeur de déplacement non trivial ou un opérateur d'affectation de déplacement.

Ce ne serait pas possible même si data_2 était un std :: vector ?

Ajouter sans copier (ou déplacer) ne serait même pas possible.

Note de bas de page 1: Vous pouvez remplacer tout le contenu d'un vecteur par le contenu d'un autre vecteur sans copier (ou déplacer) aucun élément en utilisant l'opérateur d'assignation de déplacement du vecteur.

Note 2: Vous pouvez fusionner deux instances de conteneurs basés sur des nœuds tels que les std :: list , std :: set , std :: map et leurs équivalents non ordonnés sans copier (ni déplacer) aucun des éléments.


0 commentaires

0
votes

Oui, vous pouvez. Mais alors vous devrez avoir un allocateur personnalisé pour le vecteur.

Par défaut, vector utilise std: : allocator , et vous pouvez utiliser vector :: get_allocator pour obtenir l'objet allocator. Vous pouvez essayer d'utiliser la méthode allocator :: construct pour certaines manipulations (je n'ai pas creusé plus profondément là-dessus).

Lorsque vous instanciez un vecteur , vous pouvez passer un allocateur personnalisé au vecteur, ce qui aiderait à utiliser la mémoire déjà allouée ( placement nouveau ), ou toute autre mémoire fonction d'allocation. Cet article peut vous aider .

Cependant, je ne pense pas qu'un tel effort soit vraiment fructueux.


1 commentaires

Est-il possible d'écrire un allocateur qui donne accès à deux blocs de mémoire indépendants comme s'ils n'en étaient qu'un?