Flexible Arrays — Linux Kernel Part1
Linux kernel üzerinde bellek yönetimi ile ilgili uğraşanların bilmesi gereken konulardan birisi de “Flexible Arrays”(Esnek Diziler) kavramıdır.
Bellek yönetimi denildiğinde çoğumuzun aklına “Memory consuption(Bellek tüketimi)” gelebilir.Ancak “memory consuption” ilk sırada olan bir kavram olmamalıdır. Çünkü memory management’in ilk kavramı daima “memory security(bellek güvenliği)”’dir.
Eğer bu kavrama dikkat edilmez ise,diğer kavramlar kesin olarak önemini kaybederler. Dolayısıyla memory management temelinde memory security barındırır ve diğer kavramlar bunun üzerine inşa edilmiştir.Eğer bu kavramı temel kural olarak benimser isek,diğer kavramlar buna bağlı olarak stabilitesini kuruyacaktır. Bu makalede inceleyeceğimiz “Flexible arrays” konusu da öncelikle memory security ve buna bağlı olarak memory consuption kavramlarını kapsar.
Flexible Arrays’ı iki part halinde inceleyeceğiz. Bu part’da “Flexible Array”’ı C içinde kullanımını göreceğiz.
Diğer part ise “Flexible Arrays — Linux Kernel Part2” ismiyle yer alacaktır. Part2'de Flexible Arrays’ın linux kernel içindeki kullanımını inceleyeceğiz.
Android Kernel “flex_array.c” dosyası.
Linux Kernel “flex_array.c” dosyası.
Flexible Array-C
İlk olarak normal bir array kullanarak bir “person” yapısı oluşturacağız. Daha sonra flexible array kullanacağız ve iki kullanımı karşılaştıracağız. Aşağıdaki yapıda “person” tanımlaması yapılmıştır.
typedef struct
{
char name[10];
char gender;
char age;
} normal_person;
Yukarıda verilen yapıda “name” için 10 byte yer ayırdık. Dolayısıyla name için bellekte ayrılacak alan boyutu 10 byte olacaktır. Aşağıdaki örneği inceleyelim.
Output:
normal_person boyut: 12
Görüldüğü gibi tanımladığımız yapının boyutu 12 byte. Şimdi aşağıda verilen örneği inceleyelim.
Yukarıdaki kullanımda name alanına 3 byte’lik veri atanmıştır. Atanan veri ve artı olarak NULL karakterini de hesaplarsak toplamda 4 byte’lik alan kullanılmıştır.
Soru: Geriye kalan 6 byte’lik alana ne oldu? Çünkü name[10] boyutuna sahipti.
Cevap: Geriye kalan 6 byte’lik bellek boşta kalacak.Yani işer yaramaz bellek olarak varlığını sürdürecektir.
Soru: Peki name’a “Ezo” yerine “Ezo Altunkaynak”,yani 15 byte’lık veri atadığımızda ne olacak?
Yukarıdaki yapıyı değiştirmeden sadece atanan veriyi değiştirerek çıktıyı inceleyelim.
Çıktıyı incelediğimizde alan yetersizliği nedeniyle bitişikte bulunan alan üzerine yazıldığını görüyoruz.Dolayısıyla memory security ihlali gerçekleşiyor.
Soru:Peki bu yapıyı illa böyle mi kullanmamız gerekir?
Cevap: Elbette yapı içinde yer alan “name”’i pointer olarak tanımlarsak ve “malloc” ile dinamik memory tahsisi yaparak bu sorunu çözebiliriz. Aşağıdaki örnekte “name” pointer olarak tanımlanıyor.
Yukarıda verilen örneğin çıktısı kusursuz olacaktır. Ancak bu kullanımı flexible array kullanımıyla performans bakımından karşılaştırırsak,bu yöntem hantal kalacaktır.
Flexible Array Tanımlama
Yukarıda incelediğimiz standart dizi mantığında,tanımlanan dizi sabit kalır ve dolayısıyla esnek değildir. Ancak flexible array’lar sabit bir boyuta sahip olmayacağı için,dolayısıyla bu diziler esnektir. Aşağıda flexible array tanımlamasına yer verilmiştir.
Output:
flex_person boyut: 2
Bu örnekte iki şey dikkatinizi çekmiştir. İlki “struct” yapısı,diğeri ise programın çıktısı olmuştur. Evet programın çıktısı şaşırtıcı şekilde 2 byte olarak yapı boyutunu göstermektedir. Flexible array kullanmaya başladığımızda görüldüğü gibi avantajlar da başlıyor.
Eğer flexible array kullanıyorsak,iki önemli kurala dikkat etmemiz gerekir. Bunlar:
- flexible array struct içinde en son eleman olarak yer almalıdır.
- flexible array tanımlı struct’da flexible array elemanından önce en az bir adet isimlendirilmiş eleman yer almalıdır.
Aşağıda “DOĞRU TANIMLAMA” ve “YANLIŞ TANIMLAMA” olarak belirtilmiş yapı(struct) örneklerine yer verilmiştir.
DOĞRU TANIMLAMA: Flexible array yapı içinde son eleman olarak yer alır.
typedef struct
{
char gender;
char age;
char name[];
} FLEX_person;
YANLIŞ TANIMLAMA: Flexible array yapı içinde ilk eleman olamaz.
typedef struct
{
char name[];
char gender;
char age;
} FLEX_person;
YANLIŞ TANIMLAMA: Flexible array yapı içinde tek başına tanımlanamaz.
typedef struct
{
char name[];
} FLEX_person;
Aşağıda flexible array tanımlamasına yer verilmiştir.Bu örnek ile flexible array kullanımına giriş yapıyoruz.
Flexible Array Kullanımı
Yukarıda son olarak flexible array tanımlamasını gördük. Şimdi bunu nasıl kullanacağımızı bir örnek üzerinden göreceğiz.
KAYNAKLAR:
https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Zero-Length.html
https://www.kernel.org/doc/html/v4.14/core-api/flexible-arrays.html
https://elixir.bootlin.com
https://android.googlesource.com
-end of