Armazenando um inteiro assinado em uma struct

votos
2

Eu escrevi este pedaço de código onde eu atribuído um inteiro sem sinal para duas estruturas diferentes. Na verdade eles são o mesmo, mas um deles tem o __ __attribute ((embalado)).


  #include 
  #include 

  struct st1{
    unsigned char opcode[3];
    unsigned int target;
  }__attribute__((packed));

  struct st2{
    unsigned char opcode[3];
    unsigned int target;
  };


  void proc(void* addr) {
    struct st1* varst1 = (struct st1*)addr;
    struct st2* varst2 = (struct st2*)addr;
    printf(opcode in varst1: %c,%c, %c\n,varst1->opcode[0],varst1->opcode[1],varst1->opcode[2]);
    printf(opcode in varst2: %c,%c,%c\n,varst2->opcode[0],varst2->opcode[1],varst2->opcode[2]);
    printf(target in varst1: %d\n,varst1->target);
    printf(target in varst2: %d\n,varst2->target);

  };

  int main(int argc,char* argv[]) {
    unsigned int* var;
    var =(unsigned int*) malloc(sizeof(unsigned int));
    *var = 0x11334433;

    proc((void*)var);

    return 0;
  }

A saída é:

opcode in varst1: 3,D,3
opcode in varst2: 3,D,3
target in varst1: 17
target in varst2: 0

Dado que eu estou armazenando este número 0x11334433 == 00010001001100110100010000110011

Eu gostaria de saber por que é a saída que recebo.

Publicado 19/05/2009 em 14:55
fonte usuário
Em outras línguas...                            


3 respostas

votos
3

Isto tem a ver com o alinhamento de dados. A maioria dos compiladores irá alinhar dados sobre limites de endereços que ajudam com o desempenho geral. Então, no primeiro caso, a estrutura com o atributo embalado, existe um byte extra entre o caractere [3] e o int para alinhar o int em um limite de quatro bytes. Na versão embalado que byte estofamento está faltando.

byte  :      0       1         2         3      4   5   6   7
st1   : opcode[0] opcode[1] opcode[2] padding |----int------|
st2   : opcode[0] opcode[1] opcode[2] |-------int--------|

Você atribuir um unsigned int e passar isso para a função:

byte  :      0       1         2         3      4   5   6   7
alloc :   |-----------int------------------| |---unallocated---|
st1   : opcode[0] opcode[1] opcode[2] padding |----int------|
st2   : opcode[0] opcode[1] opcode[2] |-------int--------|

Se você estiver usando um sistema endian pouco, em seguida, as mais baixas oito bits (mais à direita) são armazenados no byte 0 (0x33), byte 1 tem 0x44, byte 2 tem 0x33 e byte 4 tem 0x11. Na estrutura st1 o valor int é mapeada para a memória para além da extremidade do montante atribuído e a versão ST2 o menor byte do int é mapeado para o byte de 4, 0x11. Então st1 produz 0 e ST2 produz 0x11.

Você tem sorte que a memória não alocado é zero e que você não tem nenhum intervalo de verificação de memória acontecendo. Escrevendo aos ints em ST1 e ST2, neste caso, poderia corromper a memória na pior das hipóteses, gerar erros de guarda de memória ou não fazer nada. Ele é indefinido e dependente da aplicação de tempo de execução do gerenciador de memória.

Em geral, evite void *.

Respondeu 19/05/2009 em 15:07
fonte usuário

votos
1

Seus bytes parecido com este:

00010001 00110011 01000100 00110011

Embora, obviamente, a sua ordenação é errado e na verdade eles são assim:

00110011 01000100 00110011 00010001

Se a sua estrutura é embalado em seguida, os três primeiros bytes são associados com código de operação, eo quarto é alvo - é por isso que a matriz embalado tem atarget de 17 - 0001001 em binário.

A matriz é desempacotado preenchidos com zeros, que é por isso alvo em varst2 é zero.

Respondeu 19/05/2009 em 15:01
fonte usuário

votos
0
  • % C interpreta o argumento de que o código ASCII de um caráter e imprime o caráter
  • código ASCII 3 é 0x33
  • código ASCII D's é 0x44
  • 17 é 0x11

um int é armazenado little endian ou big endian dependendo da arquitetura do processador - você não pode depender de ele entrar em campos do seu struct em ordem.

O alvo int na versão descompactada é passado a posição do int, assim que permanece 0.

Respondeu 19/05/2009 em 15:00
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more