schnorr / mlp

Disciplina de Modelos de Linguagens de Programação - INF/UFRGS
19 stars 11 forks source link

CATP 9 - Exercício 9 #21

Closed LucasAlegre closed 5 years ago

LucasAlegre commented 6 years ago

A seguinte struct:

struct chave { char name[9]; struct { char c; char k; } element_yielded; int x; };

possui 16 bytes,

1º palavra de 8 bytes = 8 primeiros caracteres de name

A segunda palavra é: 2º palavra de 8 bytes = nono char + c + k + x + 1byte jogado fora ou 2º palavra de 8 bytes = nono char + c + k + 1byte jogado fora + x

Há esse alinhamento interno dentro da palavra de 8 bytes? A resposta diz que é a segunda opção, porque não poderia ser a primeira opção?

Obrigado.

schnorr commented 6 years ago

Veja discussão em #6. É uma questão ainda em aberto, pois tudo depende.

btrevizan commented 6 years ago

Eu tenho outra dúvida, mas um pouco relacionada com isso. Por que c e k ocupam a mesma palavra do último char de name? Eu calculei (errado) como se name perdesse 7 bytes, ou seja,

1ª palavra: name[0-7] 2ª palavra: name[8] + 7 bytes 3ª palavra: c + k + x + 2 bytes

schnorr commented 6 years ago

@btrevizan e @LucasAlegre Considere o seguinte programa:

#include <stdio.h>

typedef struct chave {
  char name[9];
  struct {
    char c;
    char k;
  } element_yielded;
  int x;
} nosso_tipo_t;

int main (int argc, char **argv)
{
  nosso_tipo_t var;
  printf("tamanho: %lu\n", sizeof(var));

  void *base = &var;
  void *endereco_e = &var.element_yielded;
  void *endereco_c = &var.element_yielded.c;
  void *endereco_k = &var.element_yielded.k;
  void *endereco_x = &var.x;

  printf("base: %p\n"
     "element_yielded: %p (distancia da base: %ld)\n"
     "c: %p (distancia da base: %ld)\n"
     "k: %p (distancia da base: %ld)\n"
     "x: %p (distancia da base: %ld)\n",
     base,
     endereco_e, endereco_e - base,
     endereco_c, endereco_c - base,
     endereco_k, endereco_k - base,
     endereco_x, endereco_x - base);
}

Compilado com gcc ou clang em 64 bits (palavra 8 bytes). Ao executar, temos esta saída:

tamanho: 16 base: 0x7ffc74e50218 element_yielded: 0x7ffc74e50221 (distancia da base: 9) c: 0x7ffc74e50221 (distancia da base: 9) k: 0x7ffc74e50222 (distancia da base: 10) x: 0x7ffc74e50224 (distancia da base: 12)

Ou seja, é a segunda opção que levantaste.

Uma possível explicação tem a ver com o alinhamento de todos os elementos. A variável x sendo inteira (portanto de 4 bytes) só pode começar no endereço 0 ou 4 de uma palavra de 8 bytes. Na tua solução, @btrevizan, ela começa no endereço 2, e portanto ocupa os endereços 2, 3, 4, e 5 da palavra. Isso em princípio não está alinhado nem alinhado no meio.