---
title: "Pointer Cast Alignment — Como Resolver em Zig"
url: "https://ziglang.com.br/erros/pointer-cast-alignment-como-resolver-em-zig/"
markdown_url: "https://ziglang.com.br/erros/pointer-cast-alignment-como-resolver-em-zig.MD"
description: "Entenda o erro de alinhamento em cast de ponteiros em Zig. Veja por que @ptrCast pode falhar e como garantir alinhamento correto de memória."
date: "2026-02-21"
author: "Zig Brasil"
---

# Pointer Cast Alignment — Como Resolver em Zig

Entenda o erro de alinhamento em cast de ponteiros em Zig. Veja por que @ptrCast pode falhar e como garantir alinhamento correto de memória.


# Pointer Cast Alignment — Como Resolver em Zig

## O Que Este Erro Significa

O erro de alinhamento em cast de ponteiros ocorre quando você tenta converter um ponteiro para um tipo que exige um alinhamento de memória mais restrito do que o ponteiro original garante. Cada tipo em Zig tem um requisito de alinhamento — por exemplo, um `u32` precisa estar em um endereço múltiplo de 4. Se um ponteiro `*u8` (alinhamento 1) for convertido para `*u32` (alinhamento 4) e o endereço não for múltiplo de 4, ocorre um erro.

Em builds Debug, a mensagem é um panic:

```
thread 1 panic: incorrect alignment
```

Em hardware, acessar dados desalinhados pode causar crashes, resultados incorretos ou penalidades severas de desempenho, dependendo da arquitetura.

## Causas Comuns

### 1. Cast de []u8 para Ponteiro de Tipo Maior

```zig
pub fn main() void {
    var buffer = [_]u8{ 0, 1, 2, 3, 4, 5, 6, 7 };
    // Pega um slice começando no byte 1 (endereço ímpar)
    const slice = buffer[1..5];
    // PANIC: endereço pode não ser alinhado a 4 bytes
    const ptr: *const u32 = @ptrCast(@alignCast(slice.ptr));
    _ = ptr.*;
}
```

### 2. Interpretar Bytes de Rede como Struct

```zig
const Cabecalho = struct {
    tipo: u32,    // Requer alinhamento 4
    tamanho: u32, // Requer alinhamento 4
};

pub fn main() void {
    var dados = [_]u8{ 0, 0, 0, 1, 0, 0, 0, 10, 0, 0 };
    // PANIC: dados[1..] pode não estar alinhado para Cabecalho
    const cab: *const Cabecalho = @ptrCast(@alignCast(dados[1..].ptr));
    _ = cab;
}
```

### 3. Cast de anyopaque para Tipo Específico

```zig
pub fn main() void {
    var byte: u8 = 42;
    const opaque: *anyopaque = &byte;
    // PANIC: byte tem alinhamento 1, u64 requer 8
    const ptr: *u64 = @ptrCast(@alignCast(opaque));
    _ = ptr;
}
```

### 4. Callback com Contexto Genérico

```zig
fn callback(context: *anyopaque) void {
    // PANIC: context pode não estar alinhado para u64
    const dados: *u64 = @ptrCast(@alignCast(context));
    _ = dados;
}

pub fn main() void {
    var byte: u8 = 1;
    callback(&byte);
}
```

### 5. Manipulação de Buffer de I/O

```zig
const std = @import("std");

pub fn main() void {
    var buffer: [1024]u8 = undefined;
    // Offset arbitrário pode quebrar alinhamento
    const offset: usize = 3;
    const ptr: *u32 = @ptrCast(@alignCast(&buffer[offset]));
    // PANIC se offset não é múltiplo de 4
    _ = ptr;
}
```

## Como Corrigir

### Solucao 1: Usar @alignCast com Verificação

```zig
const std = @import("std");

pub fn main() void {
    var buffer: [1024]u8 = undefined;
    const offset: usize = 4; // Múltiplo de 4

    // @alignCast verifica o alinhamento em runtime (Debug)
    const ptr: *align(1) u32 = @ptrCast(&buffer[offset]);
    _ = ptr;
}
```

### Solucao 2: Usar std.mem.bytesAsSlice

```zig
const std = @import("std");

pub fn main() void {
    var buffer align(4) = [_]u8{ 0, 0, 0, 1, 0, 0, 0, 2 };
    // bytesAsSlice cuida do alinhamento automaticamente
    const valores = std.mem.bytesAsSlice(u32, &buffer);
    std.debug.print("primeiro: {}\n", .{valores[0]});
}
```

### Solucao 3: Usar std.mem.readInt para Bytes Desalinhados

```zig
const std = @import("std");

pub fn main() void {
    const buffer = [_]u8{ 0, 0, 0, 1, 0, 0, 0, 2 };
    // readInt funciona com qualquer alinhamento
    const valor = std.mem.readInt(u32, buffer[1..5], .big);
    std.debug.print("valor: {}\n", .{valor});
}
```

### Solucao 4: Declarar Buffer com Alinhamento Explícito

```zig
const std = @import("std");

pub fn main() void {
    // align(4) garante que o buffer começa em endereço alinhado a 4
    var buffer: [1024]u8 align(4) = undefined;
    // Agora é seguro ler como u32 nos offsets corretos (0, 4, 8, ...)
    const ptr: *u32 = @ptrCast(&buffer[0]);
    ptr.* = 42;
}
```

### Solucao 5: Usar packed struct para Dados de Rede

```zig
const std = @import("std");

const Cabecalho = packed struct {
    tipo: u32,
    tamanho: u32,
};

pub fn main() void {
    const buffer = [_]u8{ 0, 0, 0, 1, 0, 0, 0, 10 };
    // packed struct não tem requisitos de alinhamento interno
    const cab: Cabecalho = @bitCast(buffer);
    std.debug.print("tipo: {}, tamanho: {}\n", .{ cab.tipo, cab.tamanho });
}
```

### Solucao 6: Copiar para Variável Alinhada

```zig
const std = @import("std");

pub fn main() void {
    const buffer = [_]u8{ 0, 0, 0, 42 };
    // Copia os bytes para uma variável com alinhamento correto
    var valor: u32 = undefined;
    const dest: [*]u8 = @ptrCast(&valor);
    @memcpy(dest[0..4], &buffer);
    std.debug.print("valor: {}\n", .{valor});
}
```

## Entendendo Alinhamento

### Requisitos de Alinhamento Comuns

| Tipo | Alinhamento |
|------|-------------|
| `u8` / `i8` | 1 byte |
| `u16` / `i16` | 2 bytes |
| `u32` / `i32` / `f32` | 4 bytes |
| `u64` / `i64` / `f64` | 8 bytes |
| `u128` / `i128` | 16 bytes |
| Ponteiros | 4 ou 8 bytes (plataforma) |

### Verificar Alinhamento em Comptime

```zig
const std = @import("std");

pub fn main() void {
    comptime {
        @compileLog("u32 align:", @alignOf(u32));   // 4
        @compileLog("u64 align:", @alignOf(u64));   // 8
        @compileLog("u8 align:", @alignOf(u8));     // 1
    }
}
```

## Erros Relacionados

- [Type coercion failed](/erros/erro-coercion-failed/) — Falha na coerção de tipos
- [Segmentation fault](/erros/erro-segmentation-fault/) — Consequência de acesso desalinhado em algumas plataformas
- [Packed struct layout](/erros/erro-packed-struct-layout/) — Problemas com layout de packed struct
- [Slice type mismatch](/erros/erro-slice-type-mismatch/) — Incompatibilidade de tipos de slice

## Links Úteis

- [Documentação oficial do Zig — Alignment](https://ziglang.org/documentation/master/#Alignment)
- [Builtins: @alignCast, @ptrCast](/builtins/)
- [Receitas de manipulação de bytes](/receitas/)
