2011-12-15 11 views
7

Aquí está el código en cuestiónC Aritmética de punteros sizeof (struct)

#include <stdio.h> 

struct test { 
    unsigned char t; 
    unsigned short u; 
    unsigned char v; 
}; 


int main() 
{ 
    struct test * a = (void *) 0x1000; 

    printf("%x %p %p\n", 
      sizeof(struct test), 
      a + sizeof(struct test), 
      a - sizeof(struct test)); 

    return 0; 
} 

El sizeof (test struct) imprime 6, por lo que sería esperar para ver:

6 0xffa 0x1006

En vez consigo

6 0x1024 0xfdc 

última vez Ic Heck, 0x24 o 36, no era igual a 6. Ni siquiera está alineado con nada que yo pueda decir. Estoy en una pérdida completa.

¿Puede alguien explicarme por qué obtengo estos valores?

Respuesta

16

El problema es que cuando se realiza la aritmética del puntero, se incrementa en un múltiple del tamaño del tipo de datos.

Entonces, lo que está haciendo efectivamente es agregar el cuadrado de sizeof(struct test).

Desde sizeof(struct test) = 6, está incrementando la dirección por 6 * 6 = 36. De ahí por qué obtiene 0x1024 y 0xfdc en lugar de 0x1006 y 0xffa. (También cambió el + y -, pero eso es una cosa pequeña.)

su lugar, simplemente hacer esto:

printf("%x %p %p\n", 
     sizeof(struct test), 
     a + 1, 
     a - 1); 
1

Tiene un puntero tipeado.

Así que cuando lo incrementas mi 1 (es decir, a + 1) significa a + sizeof(type).

Así a + sizeof(type)a + sizeof(type) * sizeof(type) = = a + 6 * 6 (en su caso como sizeof (test) = 6)

Ahí es donde está recibiendo 0x24 o 36 desde.

2

Creo que busca a + 1 y a - 1.

(a + x) es lo mismo es &a[x].

+2

Probablemente quiera decir que '* (a + x)' es lo mismo que 'a [x]' o que '(a + x)' es lo mismo que '& a [x]'. –

4

Al hacer una aritmética de puntero como esta, avanza o retrocede en esa cantidad de elementos, como si esa variable estuviera en una matriz. Entonces realmente quiere usar a + 1 y a - 1, que deben avanzar en 6 bytes cada vez.

IMPORTANTE: Tenga en cuenta que el compilador puede agregar relleno en su estructura para ayudar con la alineación. No asuma simplemente que debido a que tiene dos caracteres de un byte y un byte de dos bytes, su estructura tendrá 4 bytes de tamaño; este no es el caso aquí. (De hecho, no suponga que conoce el tamaño de char o corto; he visto caracteres de 2 bytes antes).

+3

En realidad eso no es del todo exacto.No se puede agregar relleno entre los elementos de la matriz. Lo que puede hacer es rellenar los elementos de una estructura y después del último elemento de una estructura (esta es probablemente la parte a la que te refieres). Pero la estructura misma está acolchada para tener el tamaño correcto si tiene requisitos de alineación: los seis bytes aquí probablemente sean 'char (1), pad (1), short (2), char (1), pad (1)' pero ese relleno final pertenece a un solo elemento de estructura, no es _entre_ elementos en un conjunto formado por esa estructura. Modo Nitpick desactivado :-) – paxdiablo

+1

Gracias, volví a redactar mi respuesta después de consultar las especificaciones C99. –