J'ai un tableau de valeurs qui est passé à ma fonction à partir d'une partie différente du programme que je dois stocker pour un traitement ultérieur. Comme je ne sais pas combien de fois ma fonction sera appelée avant qu'il ne soit temps de traiter les données, j'ai besoin d'une structure de stockage dynamique, j'ai donc choisi un fichier std::vector
. Je ne veux pas avoir à faire la boucle standard pour push_back
toutes les valeurs individuellement, ce serait bien si je pouvais simplement tout copier en utilisant quelque chose de similaire à memcpy
.
vec.assign(a, a+n)
, ce qui serait plus compact que copie et Redimensionner.Il y a eu de nombreuses réponses ici et à peu près toutes feront le travail.
Cependant, il y a quelques conseils trompeurs!
Voici les options:
Pour faire court, la méthode 4, en utilisant vector :: insert, est la meilleure pour le scénario de bsruth.
Voici quelques détails sanglants:
La méthode 1 est probablement la plus simple à comprendre. Copiez simplement chaque élément du tableau et poussez-le à l'arrière du vecteur. Hélas, c'est lent. Puisqu'il y a une boucle (implicite avec la fonction de copie), chaque élément doit être traité individuellement; aucune amélioration des performances ne peut être apportée sur la base du fait que nous savons que le tableau et les vecteurs sont des blocs contigus.
La méthode 2 est une amélioration des performances suggérée par rapport à la méthode 1; juste pré-réserver la taille du tableau avant de l'ajouter. Pour les grands tableaux, cela peut aider. Cependant, le meilleur conseil ici est de ne jamais utiliser la réserve à moins que le profilage ne suggère que vous puissiez obtenir une amélioration (ou vous devez vous assurer que vos itérateurs ne seront pas invalides). Bjarne est d'accord . Incidemment, j'ai trouvé que cette méthode était la plus lente la plupart du temps, même si j'ai du mal à expliquer en détail pourquoi elle était régulièrement beaucoup plus lente que la méthode 1 ...
La méthode 3 est la solution à l'ancienne - jetez un peu de C sur le problème! Fonctionne très bien et rapidement pour les types POD. Dans ce cas, le redimensionnement doit être appelé car memcpy fonctionne en dehors des limites du vecteur et il n'y a aucun moyen de dire à un vecteur que sa taille a changé. En plus d'être une solution moche (copie d'octets!), Rappelez-vous que cela ne peut être utilisé que pour les types POD . Je n'utiliserais jamais cette solution.
La méthode 4 est la meilleure solution. Sa signification est claire, c'est (généralement) le plus rapide et cela fonctionne pour tous les objets. Il n'y a aucun inconvénient à utiliser cette méthode pour cette application.
La méthode 5 est une modification de la méthode 4 - copiez le tableau dans un vecteur, puis ajoutez-le. Bonne option - généralement rapide et claire.
Enfin, vous savez que vous pouvez utiliser des vecteurs à la place des tableaux, non? Même lorsqu'une fonction attend des tableaux de style C, vous pouvez utiliser des vecteurs:
J'espère que cela aide quelqu'un là-bas!
la source
&expr
n'évalue pasexpr
, il ne calcule que l'adresse de celui-ci. Et un pointeur un après le dernier élément est tout à fait valable, aussi.dataVec.insert(dataVec.end(), dataArray, dataArray + dataArraySize);
- me semble beaucoup plus clair. Ne peut rien gagner de la méthode 5 non plus, cela semble assez inefficace - à moins que le compilateur ne soit capable d'optimiser à nouveau le vecteur.Si vous ne faites que remplacer les données existantes, vous pouvez le faire
la source
std :: copy est ce que vous recherchez.
la source
Comme je ne peux modifier que ma propre réponse, je vais faire une réponse composite à partir des autres réponses à ma question. Merci à tous ceux qui ont répondu.
En utilisant std :: copy , cela fonctionne toujours en arrière-plan, mais vous n'avez pas à taper le code.
Utilisation de memcpy ordinaire . Ceci est probablement mieux utilisé pour les types de données de base (ie int) mais pas pour les tableaux plus complexes de structures ou de classes.
la source
éviter le memcpy, dis-je. Aucune raison de jouer avec les opérations de pointeur à moins que vous n'ayez vraiment à le faire. De plus, cela ne fonctionnera que pour les types POD (comme int) mais échouera si vous avez affaire à des types qui nécessitent une construction.
la source
la source
myints
?Encore une autre réponse, puisque la personne a dit "Je ne sais pas combien de fois ma fonction sera appelée", vous pouvez utiliser la méthode d'insertion vectorielle comme ceci pour ajouter des tableaux de valeurs à la fin du vecteur:
J'aime cette façon parce que l'implémentation du vecteur devrait être en mesure d'optimiser la meilleure façon d'insérer les valeurs en fonction du type d'itérateur et du type lui-même. Vous répondez quelque peu sur l'implémentation de stl.
Si vous avez besoin de garantir la vitesse la plus rapide et que vous savez que votre type est un type POD, je recommanderais la méthode de redimensionnement dans la réponse de Thomas:
la source
En plus des méthodes présentées ci-dessus, vous devez vous assurer d'utiliser soit std :: Vector.reserve (), std :: Vector.resize (), ou construire le vecteur à la taille, pour vous assurer que votre vecteur a suffisamment d'éléments dans pour conserver vos données. sinon, vous corromprez la mémoire. Ceci est vrai pour std :: copy () ou memcpy ().
C'est la raison pour laquelle vous utilisez vector.push_back (), vous ne pouvez pas écrire au-delà de la fin du vecteur.
la source
En supposant que vous connaissiez la taille de l'élément dans le vecteur:
http://www.cppreference.com/wiki/stl/vector/start
la source