2012-04-26 28 views
6

estoy recibiendo un comportamiento inusual con mi código, que es el siguienteComportamiento del operador sizeof en C

#include<stdio.h> 
struct a 
{ 
    int x; 
    char y; 
}; 
int main() 
{ 
    struct a str; 
    str.x=2; 
    str.y='s'; 
    printf("%d %d %d",sizeof(int),sizeof(char),sizeof(str)); 
    getch(); 
    return 0; 
} 

Por esta pieza de código que estoy recibiendo la salida:

4 1 8 

A partir de mi conocimiento la estructura contiene una variable entera de tamaño 4 y una variable char de tamaño 1, por lo tanto, el tamaño de la estructura a debe ser 5. Pero, ¿cómo es que el tamaño de la estructura es 8. Estoy usando un compilador visual de C++. ¿Por qué este comportamiento?

+2

En 'printf()' argumentos que realmente debe convertir los valores 'sizeof' a' (int) '... o' (unsigned long) 'y use' "% lu" '... o, si tiene C99, use '"% zu "'. – pmg

+2

@pmg: Exactamente. Porque 'sizeof()' devuelve un valor de tipo 'size_t'. –

Respuesta

12

Se llama Structure Padding

Tener estructuras de datos que comienzan el 4 de alineación de palabras bytes (en la CPU con 4 autobuses byte y procesadores) es mucho más eficiente cuando se mueve en torno a los datos de la memoria, y entre la memoria RAM y la CPU.

En general, puede desactivar esto con opciones de compilación y/o pragmas, los detalles de hacerlo dependerán de su compilador específico.

Espero que esto ayude.

+1

_ Generalmente, puede desactivar esto_, pero recomiendo no hacerlo, incluso si necesita analizar un paquete binario y tener una idea para crear una estructura similar para la codificación/decodificación sin esfuerzo. Recuerde, que en algunos objetivos (tal vez en el pasado solamente) ¡la lectura desalineada podría provocar la falla del procesador! Además, esto hace que tu código sea totalmente imposible de usar. – Yury

+0

@Yury: si el compilador permite '#pragma pack' o cosas similares en dichas plataformas, normalmente generará código para solucionar el problema de lectura alineado (típicamente' memcpy' a una ubicación separada y alineada), de lo contrario, dichas estructuras serían inutilizables. . –

8

El compilador inserta relleno para fines de optimización y alineación. Aquí, el compilador inserta 3 bytes ficticios entre (o después) sus dos miembros.

Puede manejar la alineación con la directiva #pragma.

+1

quizás (1) 3 bytes y (2) después de – Vlad

+0

Sí, son 3 bytes en este caso, pero creo que está entre, ¿no es así? – md5

+0

bueno, depende de la endianidad de la máquina de destino :) ya sea iiiidddc o iiiicddd. – Vlad

0

Principalmente para ilustrar cómo funciona realmente este relleno, modifiqué un poco su programa.

#include<stdio.h> 
struct a 
{ 
    int x; 
    char y; 
    int z; 
}; 
int main() 
{ 
    struct a str; 
    str.x=2; 
    str.y='s'; 
    str.z = 13; 

    printf ("sizeof(int) = %lu\n", sizeof(int)); 
    printf ("sizeof(char) = %lu\n", sizeof(char)); 
    printf ("sizeof(str) = %lu\n", sizeof(str)); 

    printf ("address of str.x = %p\n", &str.x); 
    printf ("address of str.y = %p\n", &str.y); 
    printf ("address of str.z = %p\n", &str.z); 

    return 0; 
} 

Tenga en cuenta que agregué un tercer elemento a la estructura. Cuando ejecuto este programa, obtengo:

[email protected]:~/so$ ./padding 
sizeof(int) = 4 
sizeof(char) = 1 
sizeof(str) = 12 
address of str.x = 0x7fffc962e070 
address of str.y = 0x7fffc962e074 
address of str.z = 0x7fffc962e078 
[email protected]:~/so$ 

La parte de esto que ilustra el relleno se resalta a continuación.

address of str.y = 0x7fffc962e074 
address of str.z = 0x7fffc962e078 

Mientras que y tiene solo un carácter, tenga en cuenta que z es un total de 4 bytes a lo largo.

Cuestiones relacionadas