“Bonne” façon de stocker des données binaires avec C++/STL
En général, quel est le meilleur moyen de stocker des données binaires en C++? Les options, aussi loin que je peux dire, assez bien résumer à l'aide de cordes ou de vector<char>s. (Je vais omettre la possibilité de char*s et malloc()s depuis que je suis en se référant spécifiquement à C++).
Habituellement je viens d'utiliser une chaîne de caractères, mais je ne suis pas sûr si il y a des frais généraux, je suis absent, ou des conversions de TSL n'en interne qui pourrait plaisante pas avec la santé mentale de données binaires. Quelqu'un aurait-il une quelconque des pointeurs (har) sur ce point? Des Suggestions ou des préférences d'une manière ou d'une autre?
Vous devez vous connecter pour publier un commentaire.
vecteur de char, c'est bien parce que la mémoire est contiguious. Par conséquent, vous pouvez l'utiliser avec beaucoup de C de l'API comme berkeley ou de sockets Api de fichier. Vous pouvez effectuer les opérations suivantes, par exemple:
et il fonctionne parfaitement.
Vous pouvez le traiter comme n'importe quel autre allouée dynamiquement char tampon. Vous pouvez rechercher vers le haut et vers le bas à la recherche pour les numéros de magie ou des modèles. Vous pouvez analyser partiellement en place. Pour la réception à partir d'une prise, vous pouvez très facilement redimensionner pour ajouter encore plus de données.
L'inconvénient est le redimensionnement n'est pas terriblement efficace (redimensionner ou préallouer avec prudence) et de la suppression de l'avant de la matrice sera également très ineficient. Si vous avez besoin, par exemple, de la pop un ou deux caractères à la fois sur le devant de la structure de données très fréquemment, la copie d'un deque avant ce traitement peut être une option. Cela vous coûte une copie et deque la mémoire n'est pas contiguë, de sorte que vous ne pouvez pas simplement passer un pointeur vers un C API.
Ligne de fond, en apprendre davantage sur les structures de données et leurs compromis avant de plonger, cependant vecteur de char est typiquement ce que je vois utilisées dans la pratique générale.
char binbuf[1024]; // binary data
<br>std::vector<char> binvect = (binbuf , binbuf +1024);
const char* binvdata = vec.data();
send(sock, binvdata , vect.size() , 0 ); // wants const void*
Le plus gros problème avec les std::string, c'est que la norme actuelle ne garantit pas que son stockage sous-jacent est contiguë. Cependant, il n'existe pas de STL implémentations où la chaîne n'est pas contiguë, de sorte que, dans la pratique, il ne sera probablement pas en panne. En fait, le nouveau C++0x, le standard est de remédier à ce problème, en imposant que std::string utilise une mémoire tampon contiguë, comme std::vector.
Un autre argument à l'encontre de la chaîne, c'est que son nom suggère qu'il contient une chaîne de caractères, pas un buffer binaire, ce qui peut causer de la confusion pour ceux qui ont lu le code.
Cela dit, je recommande vecteur ainsi.
- Je utiliser
std::string
pour cela aussi, et n'ont jamais eu un problème avec elle.Un "pointeur", que je viens de recevoir un rappel brutal de 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
std::string(startIter, endIter)
constructeur de formulaire, pas de lastd::string(ptr, offset, length)
forme-cette dernière fait l'hypothèse que le pointeur pointe sur un C-chaîne de style, et ignore rien après le premier caractère zéro (il copie "jusqu'à" l'spécifiéelength
, paslength
caractères).Vous devriez certainement utiliser certains conteneurs de char, mais le conteneur que vous souhaitez utiliser dépend de votre application.
Caractères ont plusieurs propriétés qui les rendent utiles pour contenir des données binaires: la norme n'autorise pas de tout "padding" pour un char de type de données, ce qui est important car il signifie que vous n'obtiendrez pas les ordures dans le la disposition binaire. Chaque char est aussi la garantie d'exactement un octet, faisant d'elle la seule plaine de l'ancien type de données (pd) avec largeur de l'appareil (tous les autres sont spécifiés dans les termes de la supérieure et/ou inférieure de limites).
La discussion sur les conteneur stl avec lequel stocker les caractères est gérée par bien par Doug ci-dessus. Lequel vous avez besoin dépend entièrement de votre cas d'utilisation. Si vous êtes tout simplement la tenue d'un bloc de données que vous pouvez parcourir, sans recherche, ajouter/supprimer, ou la jonction des besoins, je préfère que ce vecteur, ce qui rend vos intentions de plus en plus clair que std::string, de nombreuses bibliothèques et fonctions assumer détient un nul c chaîne de style.