fixed Anahtar Sözcügü

Bildiginiz gibi C#' ta tanimladigimiz referans degiskenleri heap bellek bölgesindeki adresler temsil ederler. Ancak biz adresler yerine nesnenin ismini kullaniriz. Gereksiz bilgi toplayicis(garbage collector) bellek optimizasyonui açisindan heap bellek bölgesindeki nesnelerin yerlerini her an degistirebilir. Bu yer degisiminden bizim haberimiz olmaz, çünkü nesnenin yeri degistigi anda bu nesneye referans olan stack bellek bölgesindeki degiskenin adres bileseni de degistirilir. Dolayisiyla biz ayni referans ile farkli bellek bölgesini istegimiz disinda kullanmis oluruz. Ancak bazi durumlarda gereksiz nesne toplayicisina bir nesnenin adresini degistirmemesi için ikna etmek durumunda kaliriz. Bu, özellikle sinif nesnelerinin üye elemanlarindan birinin adresi ile islem yapmamiz gerektigi durumlarda karsimiza çikar. Bir degiskenin adresinin belirlenen bir faaliyet alani boyuncu degismeden kalmasi için bunu gereksiz nesne toplayicisina bildirmemiz gerekir. Bunun için fixed anahtar sözcügü kullanilir.
Zaten fixed anahtar sözcügünü kullanmadan referans türünden nesnelerin üye elemanlarinin adreslerini elde etmemiz mümkün degildir. Üye elemanlarinin adreslerini elde edemedigimiz bu tür nesnelere managed type(yönetilen tip) denilmektedir. Buna göre siniflar managed type kapsamina girmektedir.

Asagidaki programda ManagedType isimli sinifin int türden olan x elemaninin adresi bir göstericiye atanmak isteniyor.

using System;

class ManagedType
{
   public int x;
   public ManagedType(int x)
   {
   this.x = x;
   }
}

class Gosterici
{
   unsafe static void Main()
   {
      ManagedType mt = new ManagedType(5);

      int* ptr1 = &(mt.x);
   }
}

ManagedType sinifinin x elemani deger tipi olmasina ragmen mt nesnesi üzerinden x degiskeninin adresi elde edilememektedir. Çünkü x degiskeninin adresi gereksiz nesne toplayicisi tarafindan her an degistirilebilir. Eger yukaridaki kod geçerli olmus olsaydi x degiskeninin adresi degistigi anda ptr1 göstericisi nereye ait oldugu bilinmeyen bir adres bilgisi tasiyor olacakti. x degiskeninin bir blok içerisinde sabit adreste olmasini istiyorsak asagidaki gibi fixed anahtar sözcügünü kullanmaliyiz.

using System;

class ManagedType
{
   public int x;
   public ManagedType(int x)
   {
   this.x = x;
   }
}

class Gosterici
{
   unsafe static void Main()
   {
      ManagedType mt = new ManagedType(5);

      fixed(int* ptr1 = &(mt.x))
      {
            
//x'in adresi bu blokta asla degismez.
      }
   }
}

Yukaridaki fixed ile isaretlenmis blokta x'in adresinin degismeyecegi garanti altina alinmistir. Birden fazla degiskeni fixed olarak isaretlemek için asagidaki gibi bir kullanim geçerli kilinmistir.

ManagedType mt1 = new ManagedType(5);
ManagedType mt2 = new ManagedType(5);

fixed(int* ptr1 = &(mt1.x))
fixed(int* ptr2 = &(mt2.x))
{
   
 //x'in adresi bu blokta asla degismez.
}

Öte yandan bir fixed bildirimi içinde adreslerinin degismesini istemedigimiz elemanlari virgül ile ayirarak asagidaki gibi de bildirebiliriz.

ManagedType mt1 = new ManagedType(5);
ManagedType mt2 = new ManagedType(5);

fixed(int* ptr1 = &(mt2.x), ptr2 = &(mt2.x))
{
   
//x'in adresi bu blokta asla degismez.
}

Göstericilerle ilgili son yazýda, yapý göstericileri, göstericiler ile dizi iþlemleri ve stackalloc ile dinamik alan tahsisatý yapma gibi konularý inceleyeceðiz.