beginner_intermediate

Layout de memória de structs e classes

Como a memória é alocada em structs e classes

Seguindo o post de dependências entre headers (Dependência cíclica de headers).

Me perguntaram a razão do C++ não fazer o demangling dos nomes simplesmente quando uma variável de classe é declarada e também porque isso é diferente do Java, onde eu simplesmente coloco o nome da classe e faço um import.

No C++ podemos ter as seguintes declarações de variáveis em uma classe/struct

Já é fato conhecido que a declaração de m1 ficará na stack (pilha) e de m2/m3 será um ponteiro. O tipo de alocação de m1 é chamado de value type.

Mas como isso fica alocado em memória ?

Vamos criar uma classe message e dois packs e em seguida verificar o tamanho deles (supondo arquitetura 64-bit)

Vemos entender isso agora.
Estamos supondo que os endereços no desenho abaixo são relativos aos endereços alocados.

img1

Veja que cada tipo dentro de uma struct é adicionado por completo. Como o compilador precisa saber o tamanho exato de um tipo para poder colocá-lo dentro da struct, ele precisa fazer o parsing do arquivo. No caso da referência ou do ponteiro, somente é alocado o tamanho de um ponteiro (sizeof(void*)).

Isso é o que permite o forward declaration quando se é um ponteiro ou uma referência, já que o único tamanho que o compilador precisa saber é o tamanho de um ponteiro, este que é sempre o mesmo.

Estruturas aninhadas

Como ficaria uma estrutura aninhada então ?

img2

Conforme falamos acima, o compilador coloca os tipos alinhados. Repare pelos offsets na imagem que não há qualquer byte desperdiçado!

1 Comment

  1. Bem legal esse post.
    Alinhamento e layout são pedras no sapato de quem precisa persistir estruturas complexas no disco, para depois recuperá-las.

Leave a Reply

Your email address will not be published. Required fields are marked *