Hizalama ve Bölme
Blokları kullanılabilir ve düzenli hâle getirin.
Hizalama ve Bölme, CoddyKit'te ücretsiz bir C Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C Academy kursu toplamda 4 dersten oluşur.
Hizalama Neden Önemlidir
Her türün bir hizalama gereksinimi vardır: adresi, ikinin bir kuvvetinin katı olmalıdır. Bir double genellikle 8 baytlık hizalama gerektirir.
malloc ne saklayacağınızı bilmediğinden, en katı tür için hizalanmış işaretçiler döndürmelidir; 64 bit sistemlerde bu genellikle 16 bayttır.
#include <stdalign.h>
/* the strictest fundamental alignment */
size_t strict = alignof(max_align_t); /* often 16 */align_up Hilesi
Bir boyutu, ikinin kuvveti olan bir hizalamanın sonraki katına yuvarlamak klasik bir bit hilesidir: a - 1 ekleyin, ardından düşük bitleri maskeleyin.
Bu yalnızca a ikinin kuvvetiyse çalışır; gerçek hizalamaların tümü böyledir.
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
/* align_up(13, 8) == 16, align_up(16, 8) == 16 */Matematiğin Çalıştığını Kanıtlama
align_up işlevini çalıştırılabilir bir programla doğrulayalım. Birkaç boyutu 8 ve 16 baytlık sınırlara yuvarlar ve sonuçları yazdırır.
#include <stdio.h>
#include <stddef.h>
static size_t align_up(size_t n, size_t a) {
return (n + a - 1) & ~(a - 1);
}
int main(void) {
printf("%zu\n", align_up(13, 8)); /* 16 */
printf("%zu\n", align_up(16, 8)); /* 16 */
printf("%zu\n", align_up(1, 16)); /* 16 */
printf("%zu\n", align_up(33, 16)); /* 48 */
return 0;
}İstenen Boyutları Hizalama
Allocator içinde her isteğin ilk adımı, istenen boyutu hizalamaya göre yukarı yuvarlamaktır. Bu, sonraki bloğun da hizalı başlamasını garanti eder.
Dolgu baytları, evrensel hizalamanın bedeli olan iç parçalanmadır.
#define ALIGN 16
void *my_alloc(size_t size) {
size = align_up(size, ALIGN);
/* now find a block of this aligned size */
/* ... */
return NULL;
}Tüm Bloğu Yeniden Kullanmanın Sorunu
Önceki derste, küçük istekler için bile serbest bloğun tamamını döndürdük. 16 baytlık bir istek için verilen 4000 baytlık serbest blok, geri kalan alanı boşa harcar.
Bölme işlemi bloğu kullandığımız kısma ve serbest kalmaya devam eden bir artığa ayırır.
Bir Bloğu Bölme
Seçilen blok gerekenden çok daha büyükse, istenen bölgenin sonuna yeni bir başlık yerleştiririz. Artakalan bölüm listedeki daha küçük bir serbest blok olur.
Yalnızca artakalan bölüm bir başlıkla birlikte bir miktar yükü taşıyacak kadar büyükse böleriz; aksi halde parça işe yaramaz.
void split(block_t *b, size_t size) {
size_t rem = b->size - size;
if (rem < sizeof(block_t) + ALIGN) return; /* too small */
block_t *nb = (block_t *)((char *)(b + 1) + size);
nb->size = rem - sizeof(block_t);
nb->free = 1;
nb->next = b->next;
b->size = size;
b->next = nb;
}Ayır, Hizala, Böl
Artık eksiksiz ayırma yolu boyutu hizalar, uygun bir blok bulur, büyük bir artakalanı ayırır ve bloğu kullanılıyor olarak işaretler.
Bu, blokların boyutlarını gereksiz büyütmeden kullanılabilir serbest alan bırakır.
void *my_alloc(size_t size) {
size = align_up(size, ALIGN);
block_t *b = first_fit(size);
if (!b) return NULL;
split(b, size);
b->free = 0;
return (void *)(b + 1);
}Havuzun Kendisini Hizalı Tutma
Doğruluk için havuzun başlangıç adresi ve başlık boyutu da hizalamaya uymalıdır; böylece her yük bir sınıra oturur.
Statik arabellek üzerinde alignas kullanmak, tüm düzenin hizalı başlamasını garanti eder.
#include <stdalign.h>
alignas(16) static unsigned char pool[4096];
/* pool now begins on a 16-byte boundary */Çalıştırılabilir Hizalı Ayırma
Bu program hizalı bir havuzdan bellek ayırır ve döndürülen adresin 16'ya bölümünden kalanı yazdırır; sonucun her zaman sıfır olduğunu, yani adresin düzgün biçimde hizalandığını gösterir.
#include <stdio.h>
#include <stddef.h>
#include <stdalign.h>
static size_t align_up(size_t n, size_t a){ return (n+a-1)&~(a-1); }
alignas(16) static unsigned char pool[1024];
static size_t off = 0;
void *alloc16(size_t s){ off=align_up(off,16); if(off+s>sizeof(pool)) return NULL; void*p=&pool[off]; off+=s; return p; }
int main(void){
void *a = alloc16(1);
void *b = alloc16(20);
printf("a %% 16 = %lu\n", (unsigned long)((size_t)a % 16));
printf("b %% 16 = %lu\n", (unsigned long)((size_t)b % 16));
return 0;
}Bölme ve Birleştirme Karşılaştırması
Bölme ve birleştirme, birbirini dengeleyen zıt işlemlerdir. Ayırma büyük blokları küçülterek böler; serbest bırakma küçük blokları yeniden birleştirir.
Birlikte, aynı havuzun alan sızdırmadan veya kalıcı olarak parçalanmadan değişen istek boyutlarından oluşan bir karışıma hizmet etmesini sağlarlar.
Oyuncak Uygulamadan Gerçek Allocator'a
Artık dört temel bileşenin tümüne sahipsiniz: bir bellek kaynağı, hizalanmış başlıklar, birleştirmeli serbest liste yeniden kullanımı ve bölme. Gerçek allocator'lar hız ve ölçek için boyut sınıfı kutuları, iş parçacığı önbellekleri ve OS tümleştirmesi ekler.
Ancak burada oluşturduğunuz temel fikirler her malloc uygulamasına güç verir.
Hızlı Kontrol
Blokların ayırma sırasında neden bölündüğünü düşünün.
Özet
Hizalama, her yükün her türe uygun olması için boyutları bit hilesiyle (n + a - 1) & ~(a - 1) yukarı yuvarlar. Bölme, aşırı büyük serbest blokları kullanılan bir kısma ve serbest bir artığa ayırırken birleştirme, serbest bırakma sırasında bu işlemi tersine çevirir.
Bu dört temel bileşen birlikte eksiksiz ve doğru bir bellek allocator'ı oluşturur.
Sıkça Sorulan Sorular
“Hizalama ve Bölme” dersi ücretsiz mi?
Evet — “Hizalama ve Bölme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C Academy kursu toplamda 4 dersten oluşur.
“Hizalama ve Bölme” dersinde ne öğreneceğim?
Blokları kullanılabilir ve düzenli hâle getirin. C Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Hizalama ve Bölme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.