---
title: "@intFromPtr em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@intfromptr-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@intfromptr-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @intFromPtr em Zig. Aprenda a converter ponteiros para inteiros com exemplos práticos em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# @intFromPtr em Zig — Referência e Exemplos

Referência completa do @intFromPtr em Zig. Aprenda a converter ponteiros para inteiros com exemplos práticos em português.


# @intFromPtr em Zig

O `@intFromPtr` converte um ponteiro para seu valor numérico de endereço de memória, representado como um `usize`. Esse builtin é essencial para programação de baixo nível, incluindo desenvolvimento de sistemas operacionais, drivers e alocadores de memória personalizados.

## Sintaxe

```zig
@intFromPtr(ptr: anytype) usize
```

## O que faz

O `@intFromPtr` extrai o endereço numérico de memória contido em um ponteiro e o retorna como um valor `usize`. Essa operação é o inverso de `@ptrFromInt`. O valor retornado representa o endereço de memória virtual onde o dado apontado reside.

Esta é uma operação de baixo nível que deve ser usada com cuidado, pois trabalhar diretamente com endereços de memória pode facilmente levar a comportamento indefinido se usado incorretamente.

## Parâmetros

- **ptr** (`anytype`): Um ponteiro de qualquer tipo. Pode ser um ponteiro simples (`*T`), um ponteiro para muitos (`[*]T`), um slice (`[]T`) — neste caso, retorna o endereço do início — ou qualquer outra variante de ponteiro.

## Valor de retorno

Retorna um `usize` contendo o endereço numérico de memória do ponteiro.

## Exemplos práticos

### Exemplo 1: Obtendo o endereço de uma variável

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

test "endereço de variável" {
    var valor: u32 = 42;
    const ptr = &valor;
    const endereco = @intFromPtr(ptr);

    std.debug.print("Valor: {}\n", .{valor});
    std.debug.print("Endereço: 0x{x}\n", .{endereco});

    // O endereço é um número positivo diferente de zero
    try std.testing.expect(endereco != 0);

    // Converter de volta para ponteiro funciona
    const ptr_recuperado: *u32 = @ptrFromInt(endereco);
    try std.testing.expect(ptr_recuperado.* == 42);
}
```

### Exemplo 2: Verificação de alinhamento

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

fn estaAlinhado(ptr: anytype, comptime alinhamento: usize) bool {
    const endereco = @intFromPtr(ptr);
    return endereco % alinhamento == 0;
}

test "verificar alinhamento" {
    var buffer: [64]u8 align(16) = undefined;
    const ptr = &buffer;

    // Buffer declarado com align(16) deve estar alinhado a 16 bytes
    try std.testing.expect(estaAlinhado(ptr, 16));
    try std.testing.expect(estaAlinhado(ptr, 8));
    try std.testing.expect(estaAlinhado(ptr, 4));
}
```

### Exemplo 3: Aritmética de ponteiros para alocador personalizado

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

const AlocadorBump = struct {
    buffer: []u8,
    offset: usize,

    fn init(buffer: []u8) AlocadorBump {
        return .{ .buffer = buffer, .offset = 0 };
    }

    fn alocar(self: *AlocadorBump, tamanho: usize, comptime alinhamento: usize) ?[*]u8 {
        // Calcular endereço alinhado usando aritmética de ponteiro
        const ptr_atual = @intFromPtr(self.buffer.ptr) + self.offset;
        const alinhado = (ptr_atual + alinhamento - 1) & ~(@as(usize, alinhamento) - 1);
        const desperdicio = alinhado - ptr_atual;
        const total = desperdicio + tamanho;

        if (self.offset + total > self.buffer.len) return null;

        self.offset += total;
        return @ptrFromInt(alinhado);
    }
};

test "alocador bump" {
    var buffer: [1024]u8 = undefined;
    var alocador = AlocadorBump.init(&buffer);

    const ptr1 = alocador.alocar(32, 8);
    try std.testing.expect(ptr1 != null);
    try std.testing.expect(@intFromPtr(ptr1.?) % 8 == 0);

    const ptr2 = alocador.alocar(64, 16);
    try std.testing.expect(ptr2 != null);
    try std.testing.expect(@intFromPtr(ptr2.?) % 16 == 0);
}
```

## Casos de uso comuns

1. **Alocadores de memória personalizados**: Calcular alinhamentos, offsets e tamanhos de blocos alocados.
2. **Depuração de memória**: Imprimir endereços de ponteiros para investigar layout de memória.
3. **Verificação de alinhamento**: Verificar se um ponteiro está corretamente alinhado para operações SIMD ou requisitos de hardware.
4. **Desenvolvimento de kernel/drivers**: Trabalhar com endereços de memória mapeados em hardware.
5. **Hashing de ponteiros**: Usar o endereço como chave em tabelas hash.

## Comparação com C equivalente

Em C, a conversão de ponteiro para inteiro é feita com cast para `uintptr_t`:

```c
#include <stdint.h>
int valor = 42;
uintptr_t endereco = (uintptr_t)&valor;
```

Em Zig, o equivalente é:

```zig
var valor: i32 = 42;
const endereco: usize = @intFromPtr(&valor);
```

O tipo `usize` em Zig é equivalente a `uintptr_t` em C — ambos são garantidos ser grandes o suficiente para conter qualquer endereço de ponteiro na plataforma alvo. A diferença é que em Zig a conversão é sempre explícita com `@intFromPtr`, enquanto em C um cast de ponteiro para inteiro de tamanho errado (como `int` em vez de `uintptr_t`) é um erro silencioso em plataformas de 64 bits.

## Segurança e restrições

`@intFromPtr` é uma operação segura por si só — ela apenas lê o valor numérico do ponteiro. O perigo surge ao usar esse valor para aritmética de ponteiro manual ou ao converter de volta com `@ptrFromInt`. Em Zig, as seguintes regras se aplicam:

- Converter um endereço de volta com `@ptrFromInt` e desreferenciar um ponteiro inválido causa comportamento indefinido.
- O Zig não garante estabilidade de endereços entre execuções (ASLR, garbage collectors, etc.).
- Em ambientes com memória virtual, o endereço é um endereço virtual, não físico.

Para código de kernel que precisa de endereços físicos, use os mecanismos do sistema operacional ou do hardware para a tradução.

## Diferença entre ponteiro e slice

Ao usar `@intFromPtr` em um slice, o endereço retornado é o do primeiro elemento do slice, não um ponteiro para a struct interna do slice:

```zig
var buffer: [10]u8 = undefined;
const slice = buffer[2..8];

// Endereço do slice aponta para o primeiro elemento (buffer[2])
const end_slice = @intFromPtr(slice.ptr);
const end_buffer = @intFromPtr(&buffer);

// end_slice == end_buffer + 2 (dois bytes depois do início de buffer)
```

## Perguntas Frequentes

**P: `@intFromPtr` funciona com ponteiros opcionais (`?*T`)?**

Não diretamente. Ponteiros opcionais podem ser `null`, e `@intFromPtr` espera um ponteiro concreto. Desempacote o opcional primeiro: `@intFromPtr(opt_ptr.?)` ou verifique antes: `if (opt_ptr) |p| @intFromPtr(p)`.

**P: É seguro comparar endereços de ponteiros obtidos com `@intFromPtr`?**

Comparar endereços de ponteiros é válido em Zig para determinar se dois ponteiros apontam para o mesmo objeto ou para determinar a ordem relativa de objetos dentro do mesmo array. Porém, comparar ponteiros de objetos não relacionados produz resultados dependentes da implementação (ordem de alocação pelo sistema).

**P: Posso usar `@intFromPtr` para verificar se um ponteiro é nulo?**

Sim, `@intFromPtr(ptr) == 0` verifica se o ponteiro é nulo. No entanto, em Zig o tipo de segurança de null é gerenciado pelo sistema de tipos com ponteiros opcionais (`?*T`), então verificar ponteiro nulo dessa forma só é necessário ao interagir com APIs de baixo nível ou código C.

## Builtins relacionados

- [@ptrFromInt](/builtins/ptr-from-int/) — Operação inversa: converte inteiro para ponteiro
- [@ptrCast](/builtins/ptr-cast/) — Conversão entre tipos de ponteiro
- [@alignCast](/builtins/align-cast/) — Converte alinhamento de ponteiro
- [@alignOf](/builtins/align-of/) — Obtém o alinhamento de um tipo
- [@sizeOf](/builtins/size-of/) — Obtém o tamanho em bytes de um tipo

## Tutoriais relacionados

- [Gerenciamento de memória](/tutoriais/memoria/)
- [Ponteiros em Zig](/tutoriais/ponteiros/)
- [Programação de sistemas](/tutoriais/sistemas/)
