@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
- Duplicar slices: Criar cópias independentes de dados.
- Construir strings: Montar strings copiando partes de várias fontes.
- Serialização: Copiar structs para buffers de bytes.
- 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.copyBackwardsoustd.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