typedef ve pointer kullanımı ile ilgili bir soru

typedef ve pointer kullanımı ile ilgili bir soru

Mesajgönderen RcPaYaN » 26 Ağu 2008, 18:20

merhabalar.

kendimce glade, gtk ve c kullanarak bir program geliştiriyorum. ancak programımı geliştirme aşamasında bir takım aklıma takılan sorular oldu.

bunlardan en son olan ve nedenini bir türlü çözemedim başlıkta da söylediğim gibi bir hata. hemen açıklamaya başlıyım.

Kod: Tümünü seç
typedef struct
{
   gint a;
}
asd;


gibi bir yapı tanımladım.

Kod: Tümünü seç
asd k;


koduyla da değişken ismini belirledim. bu şekilde yaptığımda

Kod: Tümünü seç
k.a=0;


şeklinde tanımlama yaptığımda herşey normal. ancak değişkenin tanımlamasını

Kod: Tümünü seç
asd *k;


şeklinde yapıp

Kod: Tümünü seç
k->a=0;


şeklinde atamalar yapınca ve bu şekilde kullandığımda sorun çıkıyor. bildiğim kadarıyla normalde sorun olmaması gerekiyor. hatta tek bir dosya hazırlayıp yaptığım denemelerde de sorun çıkarmadı.

aslında zaten derleme aşamasında sorun çıkarmıyor. ancak programı çalıştırdığımda parçalama arızası şeklinde hata veriyor.

derlemede bir sorun yokken ve tek bir dosyada yaptığım bir denemede çalışıyorken nasıl oluyor da benim programımım çalışmaya başlayınca böyle bir hata veriyor?

işte cevabını aradığım soru bu.

kolay gelsin...
Kullanıcı avatarı
RcPaYaN
Forum Gurusu
Forum Gurusu
 
Mesajlar: 914
Kayıt: 03 Şub 2005, 01:00
Konum: İstanbul

Mesajgönderen kieroglu » 26 Ağu 2008, 19:44

Cikar cunku bir isaretci tanimlamissin ama hicbirseyi isaret etmiyor ki? malloc ile bellekten sizeof(asd) kadar yer cekip, isaretciye onu gostertmelisin:

Kod: Tümünü seç
asd *k=malloc(sizeof(asd));
k->a=0;
Kullanıcı avatarı
kieroglu
Forum Gurusu
Forum Gurusu
 
Mesajlar: 2301
Kayıt: 13 Mar 2002, 01:00
Konum: Seattle, WA

Mesajgönderen kieroglu » 26 Ağu 2008, 19:51

Biraz daha ayrinti verirsem: "hicbirseyi isaret etmiyor" dedim ama aslinda tam oyle degil, o an k isaretcisine bellekte ayrilan yerde ne varsa onu isaret ediyor, ama bu rastgele bir deger oldugu icin isaretcinin gosterdigi adrese deger atamaya kalktiginda, gosterdigi yer yasak alanlardan biri oldugu icin program cokuyor. Derleyici hata vermeyebilir; cunku teknik olarak yanlis bir islem degil ama program calistiginda hataya yol aciyor (yalniz derlemede uninitialized pointer gibi bir uyari verebilir, emin degilim).

Bir de, malloc ile bellekten yer cektigin zaman, sozkonusu degiskenle isin bitince free komutu ile bellegi serbest birakmak gerekir. Bunu yapmazsan program gocmez ama bellek kacagi (memory leak) dedigimiz, gereksiz ve gittikce biriken bellek kullanimi sorunu olusabilir.
Kullanıcı avatarı
kieroglu
Forum Gurusu
Forum Gurusu
 
Mesajlar: 2301
Kayıt: 13 Mar 2002, 01:00
Konum: Seattle, WA

Mesajgönderen RcPaYaN » 26 Ağu 2008, 21:14

syn kieroglu bilgilendirdiğiniz için teşekkürler.

aslında malloc işlemini yaptığımı hatırlıyorum ama tam olarak istediğim sonucu alamadığım için askıya almıştım ve ilk verdiğim örnekte çalıştığından dolayı sorunun buradan kaynaklanacağını düşünmemiştim.

anlamadığım şey neden ilk yöntemde çalışıyor da ikinci yöntemde bellek işlemi yapmaksızın çalışmıyor. bu konuya da aydınlık getirirseniz sevinirim.

düzeltme : birde free() fonksiyonunu argümansız gtk_main(); den sonra kullansak (nede olsa program sonlandıktan sonra bu bölümü işliyor) kullanılan tüm belleği boşaltır mı acaba?

kolay gelsin...
Mandriva2008
Kullanıcı avatarı
RcPaYaN
Forum Gurusu
Forum Gurusu
 
Mesajlar: 914
Kayıt: 03 Şub 2005, 01:00
Konum: İstanbul

Mesajgönderen kieroglu » 27 Ağu 2008, 10:45

RcPaYaN yazdı:anlamadığım şey neden ilk yöntemde çalışıyor da ikinci yöntemde bellek işlemi yapmaksızın çalışmıyor. bu konuya da aydınlık getirirseniz sevinirim.


Aslinda konunun yarisini yukarida acikladim. Soyle diyelim:

Simdi bizim struct asd tipi degiskenlerimiz bellekte 6 bayt yer tutuyor olsun (yani sizeof(asd)=6 olsun). Sen

Kod: Tümünü seç
asd k;


dedigin anda bellekten 6 bayt yer ayrilarak k degiskenine verilir. Yani buradaki k, 6 baytlik bu alanin tumudur. Bu bellek bolgesindeki veri, sen icini doldurana kadar rastgele veridir (yani RAM'in o bolgesinde onceki islemlerden ne deger kaldiysa odur). Sonra

Kod: Tümünü seç
k.a=0;


dediginde k'nin ifade ettigi 6 baytlik alandan a bilesenine karsilik gelen bolgeye 0 degeri yazilir.

Ote yandan

Kod: Tümünü seç
asd *k;


dediginde yine k adinda ama isaretci tipinde, yani gorevi bellek adresi tutmak olan bir degisken yaratilir ve ona adresi tutabilecegi kadar yer ayrilir. asd *'in anlami da, asd tipi bir yapinin adresini tutacak olmasidir ama bu o kadar onemli degil, sonucta tum bellek adresleri ayni uzunluktadir (mesela 16'li tabanda 8 basamakli gibi - orn: 0x1FA45B81). Orada asd'yi belirtmenin tek faydasi programi okuyanlara ve derleyicilere hatalari yakalama konusunda yardimci olmaktir. Yani asd tipi bir degisken beklenen yere int tipi bir degiskenin adresini gonderirsen derleyici bunu yakalar ve seni uyarir.

Simdi bellekten asd isaretcisi k icin yer ayrilir dedik ama bu ayrilan yerin icini doldurmadikca orada yine rastgele bir deger olur, mesela yine 0x1FA45B81 diyelim. Sen

Kod: Tümünü seç
k->a=0;


dediginde bilgisayar bellegin 0x1FA45B81 adresine gider, onun 6 baytlik bir asd degisken alaninin baslangici oldugunu varsayarak a bilesenine ait kisma 0 degerini yazmaya calisir. Ama tabi gittigi yer buyuk olasilikla bellegin yasak bolgelerinden biri olacagi icin bu islemi yapamaz ve program segfault ile coker.

Halbuki sen

Kod: Tümünü seç
k = malloc(sizeof(asd));


dedigin zaman bilgisayar bellekten 6 baytlik bir yer ayirir ve onun baslangic adresini, diyelim 0xAAA1111 degerini k'ya kaydeder. Simdi

Kod: Tümünü seç
k->a=0;


dediginde bilgisayar bu sefer 0xAAA111 yani dogru adrese gidip orada ilgili bolume degeri yazar.

free()'yi parametresiz kullanamazsin (diye biliyorum). Program kapandiginda/coktugunde zaten ona ayrilan tum bellek alani serbest kalir. Onemli olan uzun sure calisacak (ya da kisa sure calissa bile cokca bellek islemi yapan) programlarda bir daha kullanilmayacak bellek alanlarinin serbest birakilmasidir.
Kullanıcı avatarı
kieroglu
Forum Gurusu
Forum Gurusu
 
Mesajlar: 2301
Kayıt: 13 Mar 2002, 01:00
Konum: Seattle, WA

Mesajgönderen RcPaYaN » 27 Ağu 2008, 16:00

merhabalar.

syn kieroglu verdiğiniz bilgiler için teşekkürler. şuanda hazırlamış olduğum program hatasız çalışmaktadır. her ne kadar amatörce hazırlanmış bir program olsada bana göre fena olmadı :)

kolay gelsin...
Mandriva2008
Kullanıcı avatarı
RcPaYaN
Forum Gurusu
Forum Gurusu
 
Mesajlar: 914
Kayıt: 03 Şub 2005, 01:00
Konum: İstanbul


Dön C / C++, Mono

Kimler çevrimiçi

Bu forumu gezen kullanıcılar: Hiç bir kayıtlı kullanıcı yok ve 1 misafir