Desafio C

Padding e tamanho de struct

Enunciado

Crie duas structs com os mesmos campos, mas em ordens diferentes: A com char c; int i; char d; e B com int i; char c; char d;. Imprima sizeof(A) e sizeof(B) e explique a diferença causada pelo padding. Use typedef para ambas.

Requisitos

  • Definir typedef struct { char c; int i; char d; } A; e typedef struct { int i; char c; char d; } B;.
  • Imprimir sizeof(A) = X e sizeof(B) = Y.
  • A saída deve mostrar que sizeof(A) > sizeof(B) em plataformas típicas.

Código inicial

#include <stdio.h>

// Defina as structs A e B com typedef

int main(void) {
    // Imprima os tamanhos
    return 0;
}

Saída esperada

sizeof(A) = 12
sizeof(B) = 8
Ver dica

O compilador alinha int em múltiplos de 4; pense em onde ficam os buracos.

Mostrar solução
#include <stdio.h>

// Campos na ordem char, int, char: gera padding após o primeiro char
typedef struct {
    char c;
    int i;
    char d;
} A;

// Campos agrupados: int primeiro, depois dois chars consecutivos
typedef struct {
    int i;
    char c;
    char d;
} B;

int main(void) {
    // sizeof retorna o tamanho total incluindo padding
    printf("sizeof(A) = %zu\n", sizeof(A));
    printf("sizeof(B) = %zu\n", sizeof(B));
    return 0;
}

Passo a passo

  1. Em A, o campo char c ocupa 1 byte, mas o int i precisa de alinhamento em múltiplo de 4; o compilador insere 3 bytes de padding após c.
  2. Depois de i (4 bytes), char d ocupa 1 byte, mas a struct é alinhada ao maior campo (int), então mais 3 bytes de padding no final.
  3. Total de A: 1 + 3 (padding) + 4 + 1 + 3 (padding) = 12 bytes.
  4. Em B, int i vem primeiro (4 bytes); char c e char d ficam juntos (2 bytes) e o compilador adiciona 2 bytes de padding final para alinhar a struct a 4.
  5. Total de B: 4 + 1 + 1 + 2 = 8 bytes.
  6. sizeof retorna o tamanho em bytes; usamos %zu porque o tipo é size_t.

Por que funciona

O padding existe para que cada campo fique em um endereço alinhado, o que melhora o desempenho e é exigido por algumas arquiteturas. A ordem dos campos altera a quantidade de buracos: agrupar campos do mesmo tamanho reduz o desperdício. Por isso sizeof(A) é maior que sizeof(B).

Erros comuns

  • Assumir que sizeof é a soma dos campos: 1+4+1=6, mas o resultado é 12. Sempre consulte sizeof.
  • Usar %d para sizeof: o tipo correto é size_t, que exige %zu; caso contrário, comportamento indefinido.
  • Achar que o padding é igual em toda plataforma: depende do compilador e da arquitetura; os valores 12 e 8 são típicos em sistemas 64 bits com alinhamento de 4 bytes para int.

Outra forma de resolver

Usar #pragma pack(1) elimina o padding, mas pode causar acessos desalinhados e perda de desempenho. Só use quando o layout binário for obrigatório.

Saída esperada

sizeof(A) = 12
sizeof(B) = 8