Pregunta

En general, ¿cuál es la mejor manera de almacenar datos binarios en C ++? Las opciones, por lo que puedo decir, se reducen a usar cadenas o vectores < char > s. (Omitiré la posibilidad de char * sy malloc () s ya que me refiero específicamente a C ++).

Por lo general, solo uso una cadena, sin embargo, no estoy seguro de si faltan los gastos generales o de las conversiones que STL realiza internamente que podrían alterar la cordura de los datos binarios. ¿Alguien tiene algún puntero (har) sobre esto? ¿Sugerencias o preferencias de una forma u otra?

¿Fue útil?

Solución

El

vector de char es bueno porque la memoria es contigua. Por lo tanto, puede usarlo con una gran cantidad de API de C, como sockets berkley o API de archivos. Puede hacer lo siguiente, por ejemplo:

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

y funcionará bien.

Básicamente puede tratarlo como cualquier otro búfer de caracteres asignado dinámicamente. Puede escanear hacia arriba y hacia abajo en busca de números mágicos o patrones. Puede analizarlo parcialmente en su lugar. Para recibir desde un socket, puede cambiar su tamaño muy fácilmente para agregar más datos.

La desventaja es que cambiar el tamaño no es terriblemente eficiente (cambiar el tamaño o preasignar con prudencia) y la eliminación desde el frente de la matriz también será muy ineficiente. Si necesita, por ejemplo, hacer estallar uno o dos caracteres a la vez en la parte delantera de la estructura de datos con mucha frecuencia, copiar a una deque antes de este procesamiento puede ser una opción. Esto le cuesta una copia y la memoria de deque no es contigua, por lo que no puede simplemente pasar un puntero a una API de C.

En pocas palabras, aprenda sobre las estructuras de datos y sus compensaciones antes de sumergirse, sin embargo, el vector de char normalmente es lo que veo usado en la práctica general.

Otros consejos

El mayor problema con std :: string es que el estándar actual no garantiza que su almacenamiento subyacente sea contiguo. Sin embargo, no hay implementaciones de STL conocidas donde la cadena no sea contigua, por lo que en la práctica probablemente no fallará. De hecho, el nuevo estándar C ++ 0x solucionará este problema al exigir que std :: string utilice un búfer contiguo, como std :: vector.

Otro argumento en contra de la cadena es que su nombre sugiere que contiene una cadena de caracteres, no un búfer binario, lo que puede causar confusión a quienes leen el código.

Dicho esto, también recomiendo vector.

También uso std :: string para esto, y nunca he tenido un problema con él.

Un '' puntero '' de lo que acabo de recibir un claro recordatorio ayer en un fragmento de código: al crear una cadena a partir de un bloque de datos binarios, use el formulario constructor std :: string (startIter, endIter) , no la forma < code> std :: string (ptr, offset, length) form - este último asume que el puntero apunta a una cadena de estilo C e ignora cualquier cosa después del primer carácter cero (copia arriba) a " la longitud especificada, no los caracteres length ).

Ciertamente debería usar algún contenedor de char, pero el contenedor que desea usar depende de su aplicación.

Los caracteres tienen varias propiedades que los hacen útiles para mantener datos binarios: el estándar no permite ningún '' relleno '' para un tipo de datos char, lo cual es importante ya que significa que no obtendrá basura en su diseño binario. También se garantiza que cada carácter tiene exactamente un byte, lo que lo convierte en el único tipo de datos antiguo simple (POD) con ancho establecido (todos los demás se especifican en términos de límites superior o inferior).

La discusión sobre el contenedor stl apropiado con el cual almacenar los caracteres es manejada bien por Doug arriba. Cuál necesita depende completamente de su caso de uso. Si solo tiene un bloque de datos por el que recorre, sin necesidad de buscar, agregar / eliminar o empalmar, preferiría el vector, que hace que sus intenciones sean más claras que std :: string, que muchas bibliotecas y funciones supondrán contiene una cadena de estilo c terminada en nulo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top