Question

En général, quel est le meilleur moyen de stocker des données binaires en C ++? Autant que je sache, les options se résument à l’utilisation de chaînes ou de vecteurs . (Je vais omettre la possibilité de char * s et malloc () puisque je fais spécifiquement référence à C ++).

Habituellement, je n'utilise qu'une chaîne. Cependant, je ne suis pas sûr que certains des frais généraux ou des conversions effectuées par STL en interne puissent gâcher la validité des données binaires. Quelqu'un a-t-il des indications à ce sujet? Suggestions ou préférences d'une manière ou d'une autre?

Était-ce utile?

La solution

Le vecteur de char est agréable car la mémoire est contiguë. Par conséquent, vous pouvez l'utiliser avec de nombreuses API C, telles que les sockets berkley ou les API de fichiers. Vous pouvez effectuer les opérations suivantes, par exemple:

  std::vector<char> vect;
  ...
  send(sock, &vect[0], vect.size());

et cela fonctionnera bien.

Vous pouvez le traiter comme n'importe quel autre tampon de caractères alloué dynamiquement. Vous pouvez parcourir de haut en bas la recherche de numéros ou de modèles magiques. Vous pouvez l’analyser partiellement sur place. Pour recevoir depuis un socket, vous pouvez très facilement le redimensionner pour ajouter plus de données.

L’inconvénient est que le redimensionnement n’est pas très efficace (redimensionner ou préallouer de manière prudente) et que l’effacement de l’avant du tableau sera également très inefficace. Si vous devez, par exemple, supprimer très souvent un ou deux caractères à la fois au début de la structure de données, la copie sur un deque avant ce traitement peut être une option. Cela vous coûte une copie et une réduction de la mémoire non contiguë, vous ne pouvez donc pas simplement passer un pointeur sur une API C.

En bout de ligne, en apprendre davantage sur les structures de données et leurs compromis avant de plonger dedans, mais le vecteur de char est généralement ce que je vois utilisé dans la pratique générale.

Autres conseils

Le plus gros problème avec std :: string est que la norme actuelle ne garantit pas que son stockage sous-jacent est contigu. Cependant, il n'y a pas d'implémentations STL connues où la chaîne n'est pas contiguë. En pratique, elle n'échouera donc probablement pas. En fait, le nouveau standard C ++ 0x va résoudre ce problème, en obligeant std :: string à utiliser un tampon contigu, tel que std :: vector.

Un autre argument contre string est que son nom suggère qu'il contient une chaîne de caractères, pas un tampon binaire, ce qui peut prêter à confusion pour ceux qui liront le code.

Cela dit, je recommande également le vecteur.

J'utilise std :: string pour cela aussi, et je n'ai jamais eu de problème avec.

Un " pointeur, " dont je viens de recevoir un rappel net dans un morceau de code hier: lors de la création d’une chaîne à partir d’un bloc de données binaires, utilisez le formulaire constructeur std :: string (startIter, endIter) et non le < code> std :: string (ptr, offset, length) - ce dernier suppose que le pointeur pointe sur une chaîne de style C et ignore tout ce qui se trouve après le premier caractère zéro (il copie "up") vers "la longueur spécifiée, pas les caractères longueur ).

Vous devriez certainement utiliser un conteneur de caractères, mais le conteneur que vous souhaitez utiliser dépend de votre application.

Les caractères ont plusieurs propriétés qui les rendent utiles pour la conservation de données binaires: la norme interdit tout "remplissage". pour un type de données char, ce qui est important car cela signifie que vous n'obtiendrez pas de déchets dans votre mise en page binaire. Il est également garanti que chaque caractère correspond exactement à un octet, ce qui en fait le seul type de données ancien (POD) avec la largeur définie (tous les autres sont spécifiés en termes de limites supérieure et / ou inférieure).

Doug ci-dessus s’occupe bien de la discussion sur le conteneur stl approprié avec lequel stocker les caractères. Le type dont vous avez besoin dépend entièrement de votre cas d'utilisation. Si vous tenez juste un bloc de données que vous parcourez, sans besoin particulier de recherche, d’ajout / suppression, ni d’épissage, je préférerais vector, ce qui rend vos intentions plus claires que std :: string, ce que de nombreuses bibliothèques et fonctions assument contient une chaîne de style C terminée par un caractère null.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top