CodeBlanks Logo Icon CodeBlanks

struct layout

Struct alanlarının bellek düzenini ve sırasını öğrenirsin.

struct layout

Varsayılan (repr(Rust)) düzende derleyici alanların sırasını değiştirebilir; amacı boşluğu (padding) en aza indirmektir. Genellikle alanları hizalamaya göre büyükten küçüğe dizer. Bu düzen belgelenmiş bir garanti değildir; aynı tanım farklı derleyici sürümlerinde farklı yerleşebilir:

struct Rust { a: u8, b: u64, c: u16 }       // yeniden sıralanır: 16 bayt
#[repr(C)]
struct C { a: u8, b: u64, c: u16 }          // yazıldığı sırayla: 24 bayt

repr(C)'de: a (1) + 7 boşluk + b (8) + c (2) + 6 boşluk = 24. Rust düzeninde: b (8) + c (2) + a (1) + 5 boşluk = 16.

Düzeni gözlemlemek

offset_of!, derleyicinin seçtiği yerleşimi gösterir; -Zprint-type-sizes (nightly) tüm türlerin ayrıntılı düzenini yazdırır:

use std::mem::offset_of;

println!("{}", offset_of!(C, b));      // 8
println!("{}", offset_of!(C, c));      // 16
println!("{}", offset_of!(Rust, b));   // genellikle 0 (garanti değil)

Düzene güvenen kod (FFI, ikili dosya biçimleri, transmute) mutlaka repr(C) ya da başka bir açık repr kullanmalıdır.

Uygulama İki düzen

Aynı alanlara (a: u8, b: u64, c: u16) sahip düz struct Rust ve #[repr(C)] struct C tanımla. İkisinin size_of değerini boşlukla yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
#![allow(dead_code)]
use std::mem::size_of;

struct Rust {
    a: u8,
    b: u64,
    c: u16,
}

#[repr(C)]
struct C {
    a: u8,
    b: u64,
    c: u16,
}

fn main() {
    println!("{} {}", size_of::<Rust>(), size_of::<C>());
}

Beklenen çıktı

16 24

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Neden struct boyutu en büyük hizalamanın katına yuvarlanır?

  • Hız için rastgele
  • Yuvarlanmaz
  • İşletim sistemi ister
  • Dizideki her elemanın da doğru hizalanması için Doğru cevap

Açıklama: [T; N] içinde elemanlar arka arkaya durur; size_of::<T>() hizalamanın katı olmasaydı ikinci eleman yanlış hizalanırdı.

2 Alan konumu

Soru
use std::mem::offset_of;
println!("{}", ____!(C, b));   // 8
Cevap
use std::mem::offset_of;
println!("{}", offset_of!(C, b));   // 8

Açıklama: offset_of! bir alanın struct başından bayt uzaklığını verir.

3 Tanım ve boyut

Kavram Anlamı
Rust { a: u8, b: u64, c: u16 } 16
#[repr(C)] C { a: u8, b: u64, c: u16 } 24
offset_of!(C, b) 8 (konum)
(u8, u64) 16 (demet)

Uzman bölümündeki tüm dersler