Zig’de Many-Item Pointer’lar
Zig dilinde slice ([]T
) ile many-item pointer ([*]T
) kavramları arasında net bir ayrım vardır. Bu ayrım, array’ler, bellek işlemleri ve düşük seviye etkileşimlerde önemlidir.
Array ve Slice
Zig’de array, derleme zamanında bilinen sabit bir boyuta sahiptir:
var foo: [4]u8 = [4]u8{ 1, 2, 3, 4 };
Slice ise bellekte ardışık bir bölgeyi hem başlangıç adresi hem de uzunluk bilgisi ile birlikte tutar:
var foo_slice: []u8 = foo[0..];
Burada foo_slice
hem başlangıç adresini hem de 4 eleman içerdiği bilgisini tutar. Slice her zaman uzunluk bilgisini sakladığı için güvenlidir: Zig, elemanlara erişimde sınır kontrolü yapabilir.
std.debug.print("slice uzunluğu = {}\n", .{foo_slice.len});
Çıktı:
slice uzunluğu = 4
Many-Item Pointer’lar
Slice’lardan farklı olarak, many-item pointer sadece bellekteki adresi tutar, uzunluk bilgisi yoktur:
var foo_ptr: [*]u8 = &foo;
Bu ifade foo
’nun ilk elemanını işaret eder ama foo
’nun 4 elemanlı olduğunu bilmez. Bu yüzden yineleme veya indeksleme yaparken sorumluluk tamamen programcıya aittir:
// En az 4 eleman olduğunu *bildiğinizde* güvenli
foo_ptr[0] = 10;
foo_ptr[1] = 20;
foo_ptr[2] = 30;
foo_ptr[3] = 40;
Eğer yanlışlıkla 4 elemandan fazlasına erişirseniz Zig sizi koruyamaz:
// Tanımsız davranış: sınır dışı erişim
foo_ptr[4] = 99;
Buradaki takas şudur: hiçbir ek yük yoktur, ancak otomatik güvenlik ağı da yoktur.
Many-Item Pointer Kullanım Alanları
Multi-item pointer’lar ([*]T
) genelde performans kritik veya düşük seviye durumlarda kullanılır:
- Ham bellek erişimi: buffer okuma/yazma, memory-mapped I/O, sistem belleği ile doğrudan çalışma.
- C ile etkileşim: birçok C API’si uzunluk bilgisini paylaşmadan sadece pointer döndürür.
- Minimal ek yük: sadece adresin gerektiği durumlarda uzunluk bilgisi tutmak gereksizdir.
Örnek: C buffer’ı ile çalışma:
extern fn memset(dest: [*]u8, value: c_int, count: usize) [*]u8;
pub fn main() void {
var buffer: [16]u8 = undefined;
_ = memset(&buffer, 0, buffer.len);
std.debug.print("buffer[0] = {}\n", .{buffer[0]});
}
Burada memset
fonksiyonu [*]u8
alır çünkü C sadece ham pointer ile çalışır. Uzunluk bilgisi ayrıca count
argümanı ile iletilir.
Özet
[]T
(slice): pointer + uzunluk. Güvenli, sınır kontrolü yapılır, yüksek seviye.[*]T
(many-item pointer): sadece pointer. Güvenli değil, ham ve düşük seviye.
Günlük işlerde güvenlik için slice kullanın. Ham bellek veya dış sistemlerle çalışırken, veri sınırlarından emin olduğunuzda many-item pointer kullanın.