Uzun süredir yazamıyorum, tatil gibi bir şey yaptık bu gün bitti.
Bu gün iki tane ilginç şey öğrendim.
Birincisi integer (ve benzer 1 byte dan büyük değişken tipleri) hafıza da ters tutuluyormuş. Mesela integer 4 byte ise
[sourcecode=”cpp”]
int a = 0x04030201;
char *c = (char*)&a;
printf(“%d %d %d %dn”, *c, *(c+1), *(c+2), *(c+3));
[/sourcecode]
ekrana 1 2 3 4 basıyor. Yani a integer’ı hafıza 04 03 02 01 olarak değil de 01 02 03 04 diye tutuluyormuş. Niye böyle bir şeye gerek duydular bilmiyorum.
Bir diğer şey ise her data tipi her adrese yazılamayabiliyormuş. Mesela 4 byte olan bir integer sadece 4 ve katı olan adreslerde olabiliyor, 2 byte olan short ise sadece 2 ve katına konulabiliyor, 1 byte char ise her adreste olabiliyor.
Mesela bir structure oluşturursak
struct test{
char a;
int b;
char c;
};
bu structure adres 0x1000 de allocate edilirse o adresteki şu şekilde oluyor
a***bbbbc***
ilk önce byte olan a koyuluyor, ama ondan sonra b konulamıyor çünkü 4 ve katı adrese denk gelmiyor, 3 tane boş byte bırakılıyor ve sonra 4 bytelık b integer ı geliyor. daha sonra c geliyor ve ondan sonraki 3 byte gene kullanılamıyor.
ve sonuçta bu structure hafıza’da 12 byte kaplıyor. Eğer biz şu şekilde değiştirirsek
struct test{
char a;
char c;
int b;
};
bu sefer hafızada tutulan yapı şöyle oluyor.
ac**bbbb
ve toplam 8 byte lık yer kaplıyor.
Bu compiler a bağlı bir durum tabi. Akıllı compiler lar structure ları ikincisi gibi düzenleyebiliyormuş, fakat dev cpp bu konuyu atlamış gibi =) Bu olayın ismi struct padding miş.
Adreslendirme de bu şekilde bir zorunluluk yok, niye compiler lar böyle bir şey yapıyor bilemiyorum, eğer kodumuzun başına
#pragma pack(1)
yazarsak compiler bu olayı iptal ediyor ve bizim yazdığımız sırada ve gerçek boyutlarında hazırlıyor structure ları. Ama bir kötü yanı var ki kullanılıyor demek (belki de her mimaride çalışmıyordur)