2010-05-30 28 views
5

Ok tengo una estructura en mi programa en C++ que es así:C struct ++ que contiene unsigned char e int fallo

struct thestruct 
{ 
unsigned char var1; 
unsigned char var2; 
unsigned char var3[2]; 
unsigned char var4; 
unsigned char var5[8]; 
int var6; 
unsigned char var7[4]; 
}; 

Cuando uso esta estructura, 3 bytes aleatorios se añaden antes de la "var6", si elimino "var5", aún está antes de "var6", así que sé que siempre está antes que "var6".

Pero si elimino el "var6", los 3 bytes adicionales desaparecen.

Si solo uso una estructura con un int, no hay bytes adicionales.

Parece que hay un conflicto entre el char sin firmar y el int, ¿cómo puedo solucionarlo?

Respuesta

6

El compilador probablemente está usando su opción de alineación por defecto, donde los miembros del tamaño x están alineados en un límite de memoria divisible por x.

Dependiendo de su compilador, puede afectar este comportamiento usando un #pragma directive, por ejemplo:

#pragma pack(1) 

apagará la alineación predeterminada en Visual C++:

Especifica el valor en bytes , para ser utilizado para el embalaje. El valor predeterminado para n es 8. Los valores válidos son 1, 2, 4, 8 y 16. La alineación de un miembro estará en un límite que es un múltiplo de n o un múltiplo del tamaño de el miembro, lo que sea más pequeño.

Tenga en cuenta que, por motivos de rendimiento de CPU de bajo nivel, generalmente es mejor intentar alinear sus miembros de datos para que caigan en un límite alineado. Algunas arquitecturas de CPU requieren alineación, mientras que otras (como Intel x86) toleran la desalineación con una disminución en el rendimiento (a veces de manera significativa).

+0

gracias que funcionó – powerfear

4

¿Estás hablando de bytes de relleno? Eso no es un error. Según lo permitido por el estándar de C++, el compilador agrega relleno para mantener los miembros aligned. Esto es necesario para algunas arquitecturas, y mejorará en gran medida el rendimiento para otros.

5

Su estructura de datos es aligned de modo que su int caiga en límites de palabra, que para su destino pueden ser 32 o 64 bits.
Puede reorganizar su estructura como tal manera que esto no sucederá:

struct thestruct 
{ 
int var6; 
unsigned char var1; 
unsigned char var2; 
unsigned char var3[2]; 
unsigned char var4; 
unsigned char var5[8]; 
unsigned char var7[4]; 
}; 
+0

Una buena invocación para reorganizar la estructura, mucho mejor que utilizar pragmas/atributos de embalaje dependientes del compilador. –

+0

Todavía es implementación definida. –

0

Tiene un problema de alineación de bytes. El compilador agrega relleno para alinear los bytes. Ver this artículo de la wikipedia.

0

Lea en data structure alignment. Básicamente, dependiendo del compilador y las opciones de compilación, obtendrás la alineación en diferentes powers-of-2.

Para evitarlo, mover elementos de múltiples bytes (int o punteros) antes de un solo byte (con o sin signo carbón) artículos - aunque todavía podría estar allí después de su último artículo.

0

Mientras que cambiar el orden se declara miembros de datos dentro de su struct está muy bien, es preciso señalar que anulando la alineación predeterminada mediante #pragma s y tal es una mala idea menos que sepa exactamente lo que está haciendo. Dependiendo de su compilador y arquitectura, intentar acceder a los datos no alineados, particularmente almacenando la dirección en un puntero y luego tratando de desreferenciarlo, puede dar fácilmente el temido error de bus u otro comportamiento indefinido.