& # 8220; La corretta & # 8221; modo per memorizzare i dati binari con C ++ / STL

StackOverflow https://stackoverflow.com/questions/441203

  •  22-07-2019
  •  | 
  •  

Domanda

In generale, qual è il modo migliore per archiviare i dati binari in C ++? Le opzioni, per quanto ne so, si riducono sostanzialmente all'uso delle stringhe o dei caratteri vettoriali. (Ometterò la possibilità di char * se malloc () poiché mi riferirò specificamente al C ++).

Di solito uso solo una stringa, tuttavia non sono sicuro che ci siano spese generali che mi mancano o conversioni che STL fa internamente che potrebbero compromettere la sanità mentale dei dati binari. Qualcuno ha qualche suggerimento (har) su questo? Suggerimenti o preferenze in un modo o nell'altro?

È stato utile?

Soluzione

il vettore di char è carino perché la memoria è contigua. Pertanto è possibile utilizzarlo con molte API C come socket berkley o API file. Ad esempio, puoi fare quanto segue:

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

e funzionerà bene.

Puoi essenzialmente trattarlo come qualsiasi altro buffer di caratteri allocato dinamicamente. Puoi scansionare su e giù alla ricerca di numeri o schemi magici. Puoi analizzarlo parzialmente sul posto. Per ricevere da un socket puoi ridimensionarlo molto facilmente per aggiungere più dati.

Il rovescio della medaglia è il ridimensionamento non è terribilmente efficiente (ridimensionare o preallocare con prudenza) e anche la cancellazione dalla parte anteriore dell'array sarà molto inefficace. Se è necessario, ad esempio, estrarre molto frequentemente solo uno o due caratteri alla volta dalla parte anteriore della struttura dei dati, la copia su un deque prima di questa elaborazione può essere un'opzione. Questo ti costa una copia e deque memory non è contigua, quindi non puoi semplicemente passare un puntatore a un'API C.

In conclusione, apprendi le strutture dei dati e i loro compromessi prima di immergerti, tuttavia il vettore di carattere è in genere quello che vedo usato nella pratica generale.

Altri suggerimenti

Il problema più grande con std :: string è che lo standard attuale non garantisce che la sua memoria sottostante sia contigua. Tuttavia, non esistono implementazioni STL note in cui la stringa non è contigua, quindi in pratica probabilmente non fallirà. In effetti, il nuovo standard C ++ 0x risolverà questo problema, imponendo che std :: string usi un buffer contiguo, come std :: vector.

Un altro argomento contro stringa è che il suo nome suggerisce che contiene una stringa di caratteri, non un buffer binario, che può causare confusione a coloro che leggono il codice.

Detto questo, raccomando anche il vettore.

Uso std :: string anche per questo, e non ho mai avuto problemi con esso.

Un " pointer, " di cui ho appena ricevuto un forte promemoria in un pezzo di codice ieri: quando si crea una stringa da un blocco di dati binari, utilizzare il modulo di costruzione std :: string (startIter, endIter) , non il < code> std :: string (ptr, offset, length) - quest'ultima ipotizza che il puntatore punta a una stringa di tipo C e ignora qualsiasi cosa dopo il primo carattere zero (copia " su a " la lunghezza specificata, non length ).

Dovresti certamente usare qualche contenitore di char, ma il contenitore che vuoi usare dipende dalla tua applicazione.

I caratteri hanno diverse proprietà che li rendono utili per contenere i dati binari: lo standard non consente alcun "riempimento". per un tipo di dati char, che è importante poiché significa che non otterrai spazzatura nel tuo layout binario. È inoltre garantito che ogni carattere sia esattamente un byte, rendendolo l'unico vecchio tipo di dati (POD) con larghezza impostata (tutti gli altri sono specificati in termini di limiti superiore e / o inferiore).

La discussione sul contenitore stl appropriato con cui archiviare i caratteri è gestita bene da Doug sopra. Quale di cui hai bisogno dipende interamente dal tuo caso d'uso. Se stai semplicemente trattenendo un blocco di dati che scorre, senza alcuna ricerca speciale, aggiungi / rimuovi o necessità di giunzione, preferirei vector, il che rende le tue intenzioni più chiare di std :: string, che molte librerie e funzioni assumeranno contiene una stringa di tipo c con terminazione null.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top