---
title: "@memcpy em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@memcpy-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@memcpy-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @memcpy em Zig. Copie blocos de memória de forma eficiente entre slices. Exemplos práticos em português."
date: "2026-02-21"
author: "Zig Brasil"
---

# @memcpy em Zig — Referência e Exemplos

Referência completa do @memcpy em Zig. Copie blocos de memória de forma eficiente entre slices. Exemplos práticos em português.


# @memcpy em Zig

O `@memcpy` copia dados de um slice de origem para um slice de destino. Os slices devem ter o mesmo comprimento e não devem se sobrepor na memória. É a forma idiomática de copiar blocos de memória em Zig, frequentemente otimizada para instruções SIMD pela CPU.

## Sintaxe

```zig
@memcpy(dest: []T, source: []const T) void
```

## Parâmetros

- **dest** (`[]T`): Slice de destino (mutável).
- **source** (`[]const T`): Slice de origem (pode ser const).

Os dois slices devem ter **exatamente o mesmo comprimento**. Se tiverem comprimentos diferentes, é erro de compilação ou panic em runtime.

## Valor de retorno

`void` — a operação modifica a memória de destino diretamente.

## Exemplos práticos

### Exemplo 1: Copiar entre arrays

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

pub fn main() void {
    const origem = [_]u8{ 'Z', 'i', 'g' };
    var destino: [3]u8 = undefined;

    @memcpy(&destino, &origem);

    std.debug.print("Copiado: {s}\n", .{&destino}); // "Zig"
}
```

### Exemplo 2: Copiar parte de um slice

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

pub fn main() void {
    const dados = "Hello, Zig Brasil!";
    var buffer: [3]u8 = undefined;

    // Copiar "Zig" (posições 7..10)
    @memcpy(&buffer, dados[7..10]);

    std.debug.print("Extraído: {s}\n", .{&buffer}); // "Zig"
}
```

### Exemplo 3: Duplicar slice com allocator

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

fn duplicar(allocator: std.mem.Allocator, original: []const u8) ![]u8 {
    const copia = try allocator.alloc(u8, original.len);
    @memcpy(copia, original);
    return copia;
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();

    const original = "Zig Brasil";
    const copia = try duplicar(gpa.allocator(), original);
    defer gpa.allocator().free(copia);

    std.debug.print("Original: {s}\n", .{original});
    std.debug.print("Cópia: {s}\n", .{copia});
}
```

## Casos de uso comuns

1. **Duplicar slices**: Criar cópias independentes de dados.
2. **Construir strings**: Montar strings copiando partes de várias fontes.
3. **Serialização**: Copiar structs para buffers de bytes.
4. **Buffers de rede**: Copiar dados entre buffers de envio/recebimento.

## Regras importantes

- Os slices **não devem se sobrepor** na memória. Para cópias sobrepostas, use `std.mem.copyBackwards` ou `std.mem.copyForwards`.
- Os slices devem ter o **mesmo comprimento**. Use fatiamento (`[0..n]`) para ajustar.

## Comparação com C equivalente

Em C, `memcpy` recebe um tamanho em bytes e ponteiros sem tipo:

```c
#include <string.h>
void* src = ...;
void* dst = ...;
memcpy(dst, src, tamanho_em_bytes); // sem verificação de tipos ou tamanhos
```

Em Zig, `@memcpy` trabalha com slices tipados e o compilador verifica comprimentos:

```zig
@memcpy(destino, origem); // destino e origem devem ter o mesmo comprimento e tipo
```

A versão Zig é mais segura pois:
- O tipo dos elementos é verificado em compilação (não se pode copiar bytes de um `[]i32` para um `[]f64` sem cast explícito).
- O comprimento é verificado em runtime (modo debug) ou compilação quando possível.
- Não é necessário calcular `tamanho * sizeof(elemento)` manualmente.

## Desempenho e otimizações

O `@memcpy` é mapeado para operações de cópia de memória altamente otimizadas. O compilador pode:

- Usar instruções SIMD (SSE, AVX, NEON) para copiar múltiplos bytes por instrução.
- Aplicar loop unrolling para tamanhos conhecidos em comptime.
- Usar `rep movsb` em x86 para cópias grandes.
- Inlinar a cópia completamente para tamanhos pequenos.

Para tamanhos pequenos conhecidos em compilação (ex: copiar uma struct de 16 bytes), o compilador geralmente gera 2-3 instruções de load/store sem nenhum loop.

## Cópia de structs via slice de bytes

`@memcpy` pode ser usado para cópia bitwise de structs, tratando-as como bytes:

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

const Ponto = struct { x: f32, y: f32, z: f32 };

fn clonarPonto(p: Ponto) Ponto {
    var resultado: Ponto = undefined;
    const src = std.mem.asBytes(&p);
    const dst = std.mem.asBytes(&resultado);
    @memcpy(dst, src);
    return resultado;
}
```

No entanto, para structs simples, a atribuição direta (`resultado = p`) é mais idiomática e produz o mesmo código.

## Perguntas Frequentes

**P: O que acontece se os slices se sobrepuserem?**

Em modo debug, isso pode ser detectado e causar um panic (comportamento ilegal detectado). Em modo release, o resultado é undefined behavior — a memória pode ficar corrompida silenciosamente. Use `std.mem.copyForwards` ou `std.mem.copyBackwards` para cópias sobrepostas.

**P: Posso usar `@memcpy` para copiar slices de tipos não-u8?**

Sim. `@memcpy` funciona com slices de qualquer tipo, não apenas `u8`. Por exemplo, `@memcpy(slice_i32_dst, slice_i32_src)` copia arrays de inteiros diretamente.

**P: `@memcpy` é mais rápido que um loop manual `for`?**

Geralmente sim. O compilador otimiza `@memcpy` com instruções de cópia de memória em bloco (SIMD, `rep movs`, etc.) que são significativamente mais eficientes que loops `for` elemento a elemento, especialmente para tamanhos grandes.

## Builtins relacionados

- [@memset](/builtins/memset/) — Preenche memória com um valor
- [@sizeOf](/builtins/size-of/) — Tamanho de tipos em bytes
- [@ptrCast](/builtins/ptr-cast/) — Converter ponteiros antes de copiar

## Tutoriais relacionados

- [Gerenciamento de Memória em Zig](/tutoriais/gerenciamento-de-memoria-zig/)
- [Strings e Arrays em Zig](/tutoriais/strings-e-arrays-zig/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
