Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

259
Vistas
memcpy para copiar un búfer de longitud fija en una estructura

Tengo este código de muestra:

 struct { char a[2]; char b[2]; } buff; char buffer1[5] = "ABCD";

Para copiar el buffer1 a los miembros de la estructura, hago lo siguiente:

 char c[3],d[3]; memcpy(&buff,buffer1,4); sprintf(c,"%2.2s",buff.a); sprintf(d,"%2.2s",buff.b); printf("c=%s,d=%s",c,d);

Cuando imprimo las variables c y d, obtengo los valores en la variable c y d correctamente como: c="AB" y c="CD" .

Bueno, mi pregunta es, aunque estoy obteniendo el resultado correctamente, ¿ memcpy afectará algo relacionado con la terminación de caracteres nulos o tendrá otras consecuencias inesperadas relacionadas con la memoria?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Hay dos problemas aquí:

1) Como se mencionó en los comentarios, es probable que olvide incluir un espacio para el carácter terminador '\0' (es decir, NUL en ASCII). El especificador de formato %s para la función printf espera que la cadena de caracteres tenga un formato válido. Sin embargo, nada le impide imprimir una secuencia de caracteres, como aquí:

 #include <stdio.h> #include <string.h> struct { char a[2]; char b[2]; } buff; char buffer1[5] = "ABCD"; int main(void) { memcpy(&buff, buffer1, 4); printf("First member: %c%c\n", buff.a[0], buff.a[1]); printf("Second member: %c%c\n", buff.b[0], buff.b[1]); return 0; }

2) Un problema más grave es que el compilador puede incluir un relleno arbitrario entre los miembros de la estructura (así como después del último miembro), por lo que es posible que memcpy no funcione como se esperaba. En lugar de copiar así (ya que puede poner bytes de la matriz en "todos" no utilizados). Sugeriría copias individuales de cada miembro o tal vez usar la macro offsetof() .

De N1570 6.7.2.1/15 estructura y unión :

Puede haber relleno sin nombre dentro de un objeto de estructura, pero no al principio.

y 6.7.2.1/17 :

Puede haber relleno sin nombre al final de una estructura o unión.

Por lo tanto, debe dividir su memcpy en dos llamadas, por ejemplo:

 memcpy(&buff.a, buffer1, 2); /* or replace 2 with sizeof buff.a */ memcpy(&buff.b, buffer1+2, 2);
over 4 years ago · Santiago Trujillo Denunciar

0

buffer1 termina en nulo. Sin embargo, los miembros de datos de buff no lo son, ya que no se les agrega un terminador nulo. ¡Además, no tienes espacio para el terminador nulo!

Entonces, no, no lo afectará, ya que no está allí. Obtendrá resultados inesperados cuando intente utilizar las funciones de stdio.h , que esperan una cadena terminada en nulo.


Además, es posible que desee consultar mi ejemplo aquí , sobre el bucle en una estructura, que de alguna manera es relevante. Le sugiero que copie a un miembro de datos a la vez y no de una sola vez.

over 4 years ago · Santiago Trujillo Denunciar

0

Eso podría no funcionar como se esperaba. Puede haber bytes de relleno entre los campos de una estructura. Estos se insertan entre los campos para que el siguiente campo comience en una dirección determinada. Este es principalmente el tamaño de palabra de la CPU o el tamaño del bus, o un múltiplo del mismo para la alineación de caché.

Esto puede ser cierto incluso para char [] , ya que eso permitiría mover/copiar eficientemente dichas matrices mediante transferencias de palabras.

Para otros tipos, el relleno es muy probable y, además, debe preocuparse por la comodidad.

Recuerda también que memcpy & friends hacen exactamente lo que sus nombres implican: operan en un bloque de memoria. No les importan las cadenas, no tienen idea de "cadenas". Insertar cualquier byte NUL los haría inútiles, por lo que no lo hacen.

Tenga en cuenta que este enfoque es similar a la conversión de tipos de punteros incompatibles. Hay pocos lugares en los que estás a salvo, pero la mayoría de las veces este es el camino al infierno (también conocido como comportamiento indefinido ).

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda