@memcpy em Zig — Referência e Exemplos

@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

@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

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

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

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.

Builtins relacionados

  • @memset — Preenche memória com um valor
  • @sizeOf — Tamanho de tipos em bytes
  • @ptrCast — Converter ponteiros antes de copiar

Tutoriais relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.