Copiez le contenu de std::vector<char> dans un char* buffer?
J'ai un std::vector. Je veux copier le contenu du vecteur dans un char* tampon d'une certaine taille.
Est-il un moyen sûr de le faire?
Puis-je faire cela?
memcpy(buffer, _v.begin(), buffer_size);
ou cela?
std::copy(_v.begin(), _v.end(), buffer); //throws a warning (unsafe)
ou cela?
for (int i = 0; i < _v.size(); i++)
{
*buffer = _v[i];
buffer++;
}
Merci..
- Mon C++-fu est un peu rouillé, mais ne serait pas
char* str = &_v[0];
faire le travail? - Je ne sais pas.. 🙁
- Probablement, au moins au premier abord. Si le vecteur jamais redistribue son tampon, l'emplacement peut changer, et si le vecteur est détruit, le pointeur n'est pas valide. C'est assez risqué que ce n'est probablement pas une bonne idée.
- Que de ne pas copier le vecteur dans un autre tampon, il suffit de saisir l'adresse de la mémoire tampon interne dans le vecteur.
- Qui fonctionne parfaitement bien pour le moment et même être beaucoup plus rapide, cependant, il va casser du moment où vous ajoutez des données dans le vecteur et dépasser ses capacités. À ce moment, il va allouer un nouveau bloc et gratuit le un vous pointez.
- La vraie question est: Pourquoi voulez-vous utiliser un
char*
tampon?std::vector
est beaucoup mieux dans (presque) tous les sens. - Merci pour les réponses. Je n'ai pas tendance à traiter avec beaucoup de C ou C++ ces jours-ci, donc je n'avais pas considéré comme la réaffectation des questions. Je suppose que
&_v[0]
est toujours utile, si. Ça peut être sympa pour les cas où vous souhaitez simplement effectuer une opération rapide sur unstd::vector
où la fonction ne prendchar*
, et vous n'êtes pas inquiet au sujet des conditions de course. Encore, la meilleure pratique est une bonne copie. - quel avertissement obtenez-vous ? Un pointeur est un modèle de
RandomIterator
qui comprend les exigences pour unOutputIterator
, donc un pointeur est certainement valable pour le 3ème argument destd::copy
. Pourriez-vous nous montrer le texte de l'avertissement? - Je reçois cet avertissement: avertissement C4996: 'std::copy": appel d'une Fonction avec des paramètres qui peuvent être dangereux - cet appel s'appuie sur l'appelant pour vérifier que les valeurs passées sont corrects. Pour désactiver cet avertissement, utilisez -D_SCL_SECURE_NO_WARNINGS. Voir la documentation sur la façon d'utiliser Visual C++ 'est Coché les Itérateurs'
- Ah ok. Les avertissements en
/W4
(c'est à dire avec et ID supérieur à 4000) sont le plus souvent pas juste du bruit. Comme vous pouvez le lire, c'est juste vous avertit qu'il est de votre responsabilité de vous assurer que le tampon de destination est assez grand, parce que l'utilisation d'un pointeur nu plutôt qu'un type avancé empêche VC++ pour insérer le code de débogage pour le vérifier pour vous. Je vous conseille seulement de/W3
si vous ne voulez pas de se noyer. - La réponse dépend de ce que vous voulez faire avec le char* buffer. Veuillez fournir des précisions.
- non, pas vraiment. Le problème est que le terme "char* buffer" est trompeuse: un
char*
n'est pas un tampon. C'est un pointeur vers la mémoire tampon. Votre code dit "point à la mémoire tampon interne utilisé par lestd::vector
instance". L'effet recherché est "copier des données dans la mémoire tampon qui est actuellement en cours pointé". - Merci.. 🙂
- Désolé je crois que j'aurais dit "char tampon pointé par un char*.
Vous devez vous connecter pour publier un commentaire.
C'est la meilleure façon de le faire en C++. Il est sûr de copie de cette façon, si
buffer
est assez grand.char*
n'est pas nécessairement un c-string.\0
?std::vector<char>
est mauvais pour commencer avec, commestd::string
serait un mieux choix dans le cas où sichar*
doit être traitée avec le c-string.\0
à la fin - alors pas besoin d'ajouter plus de\0
std::string
serait un meilleur choix, vous pouvez ajouter\0
à la fin quand on fait une copie de celui-ci, et de les stocker danschar*
.std::vector<char>
au lieu destd::string
, je suppose que le vecteur s 'contenu n'est pas garantie c-string.vector<char>
est garanti d'être un bloc contigu de mémoire?.delete
. Mais vous n'avez pas état qu'avez-vous? (ni a-t-I)char*
, c'est vous qui l'assume c-string. Mais quand je voischar*
, je ne voischar*
. Aucune hypothèse. Comme je l'ai dit,char*
ne veut pas forcément dire c-string.char*
peut ou peut ne pas être un c-string. Le point est que le lecteur de code et la réponse peut facilement être induit en erreur (due à une écrasante majorité, l'utilisation fréquente dechar*
à se référer à c-strings).char *
, veuillez le déplacer pour le chat.Si vous avez juste besoin
char*
, alors vous pouvez faire ceci:Note de la modification des données pointées par
buffer
modifie le vecteur du contenu aussi!Ou si vous avez besoin d'un copie, puis allouer une mémoire de taille égale à
v.size()
octets, et l'utilisationstd::copy
:Le plus sûr moyen de copier un
vector<char>
dans unchar *
tampon est de le copier à un autre vecteur, et ensuite utiliser ce vecteur de la mémoire tampon interne:Bien sûr, vous pouvez également accéder à
_v
s de la mémoire tampon si vous n'avez pas besoin de copier les données. Aussi, méfiez-vous que le pointeur sera invalidée si le vecteur est redimensionnée.Si vous devez le copier dans un tampon, puis vous aurez besoin de savoir que la mémoire tampon est assez grand avant de les copier; il n'y a pas de limites des contrôles sur les tableaux. Une fois que vous avez vérifié la taille, votre deuxième méthode est la meilleure. (Le premier ne fonctionne que si
vector::iterator
est un pointeur, ce qui n'est pas garanti; bien que vous puissiez modifier le deuxième argument de&_v[0]
pour le faire fonctionner. La troisième est la même chose, mais c'est plus compliqué, et devrait probablement être corrigé afin de ne pas modifierbuffer
).char * buffer;{std::vector<char> copy = _v;buffer = ©[0];} cout<<buffer;
Bien, vous voulez affecter à
*buffer
pour le cas 3, mais cela devrait fonctionner. Le premier presque certainement ne fonctionne pas.EDIT: je me tiens corrigé sujet n ° 2.