[Linux-programlama] Re: C malloc free (kafama takılan bir nokta

---------

New Message Reply About this list Date view Thread view Subject view Author view Attachment view

From: Caglar Akyuz (caglar@bilkon-kontrol.com.tr)
Date: Fri 27 Apr 2007 - 19:28:45 EEST


M.Atif CEYLAN wrote:
> Caglar Akyuz yazmış:
>> M.Atif CEYLAN yazmış:
>>
>>> Ustun ERGENOGLU yazmış:
>>>
>>>> malloc ile aldığınız bellek alanları fonksiyondan çıktığınızda
>>>> boşalmaz, mutlaka free ile bırakmanız gerekir. sadece fonksiyonda
>>>> kullanılacak yerel değişkenler fonksiyona girince stack'den yer alıp
>>>> kullanır, çıkınca da bırakılır, ama malloc stack'den değil heap'den
>>>> yer alır ve program çalıştığı sürece kalır.
>>>>
>>>> 26.04.2007 tarihinde M.Atif CEYLAN <atifceylan@gmail.com> yazmış:
>>>>
>>>>
>>>>> herkese merhaba,
>>>>> arkadaşlar C de yazdığım bir programda cok yoğun string işlemleri
>>>>> kullanıyorum (10 larca mb lık dosyaları okuyup parse etmeye calışıyorum
>>>>> ve bu işlemi periyodik olarak devamlı olarak yapıyorum). ancak
>>>>> stringleri küçük parçalarda alıp her seferinde fonksiyona sokuyorum
>>>>> mesela :
>>>>>
>>>>> while (sart)
>>>>> islemyap(str)//burada en fazla 2 KB datam var
>>>>>
>>>>> islemyap(char *str)
>>>>> char *a = (char*)malloc(256);
>>>>> char *b = (char*)malloc(25);
>>>>>
>>>>> a = str_temizle(sub_str(str,3,255));
>>>>> b = str_temizle(sub_str(str,258,24));
>>>>> ........................
>>>>>
>>>>> şeklinde devam eden islemyap benzeri 4 fonksiyonum var.
>>>>> sorunum şu. fonksiyon sona erdiğinde ayrılan bellek alanları zaten
>>>>> boşalır düşüncesi ile değişkenlerimi free etmiyorum.
>>>>> ancak top cıktısı bir facia gibi adeta. her seferinde yükselen bir
>>>>> bellek var önümde. bu durum, çekirdeğin ihtiyat için benim programın
>>>>> ayırdığı bellek alanlarını tutması ile alakalı olabilir mi? yoksa
>>>>> fonksiyonların sonunda free etsem mi? ama o kadar fazla değişkenim var
>>>>> ki gözüm yemiyor daha kötüsü bazıları şartlara göre set edildiği için
>>>>> free işlemlerinde de kontrole ihtiyac duyacağım.fikirlerinizi bekliyorum
>>>>> iyi çalışmalar...
>>>>> M.Atıf CEYLAN
>>>>>
>>>>> _______________________________________________
>>>>> Linux-programlama mailing list
>>>>> Linux-programlama@liste.linux.org.tr
>>>>> http://liste.linux.org.tr/mailman/listinfo/linux-programlama
>>>>>
>>>>>
>>>>>
>>>> _______________________________________________
>>>> Linux-programlama mailing list
>>>> Linux-programlama@liste.linux.org.tr
>>>> http://liste.linux.org.tr/mailman/listinfo/linux-programlama
>>>>
>>>>
>>>>
>>> şöyle bir foksiyonum var.
>>>
>>>
>>> char *fonksiyon(char *str)
>>> {
>>> char *Cikacak = (char *malloc(strlen(str)+1);
>>>
>>> int i=0,j=0;
>>>
>>> for(i=0;i<strlen(str);i++)
>>> if (sart)
>>> Cikacak[j++] = str[i];
>>>
>>> return Cikacak;
>>> }
>>>
>> malloc her zaman başarılı olmaz. Döndürdüğü değeri mutlaka NULL mı değil
>> mi diye kontrol etmek gerekir.
>>
>>
>>> mallocladığım alanı nasıl free edebilirim ve tuttuğu alanı free
>>> edebilmek için bu foksiyonu daha mantıklı nasıl yazabilirim.
>>>
>>
>> Bence bu fonksiyon'da bir değişikliğe gerek yok. return ettiğiniz
>> "Cikacak" pointer'ını her zaman free'ye geçebilirsiniz.
>>
>>
>>> iyi Çalışmalar...
>>>
>>> _______________________________________________
>>> Linux-programlama mailing list
>>> Linux-programlama@liste.linux.org.tr
>>> http://liste.linux.org.tr/mailman/listinfo/linux-programlama
>>>
>>>
>>>
>>>
>> _______________________________________________
>> Linux-programlama mailing list
>> Linux-programlama@liste.linux.org.tr
>> http://liste.linux.org.tr/mailman/listinfo/linux-programlama
>>
>>
> char *deneme(char *a)
> {
> char *b = (char *)malloc(20);
>
> if (b == NULL)
> return null;
>
> b = a;

Oops! malloc ile ayırdığımız hafızayı çöpe attık :)
>
> printf("b :%p\t",b);
>
> return b;
> }
>
> int main(){
> char *c = (char *)malloc(20);
>
> c = deneme("deneme");

deneme içinde zaten memory i ayırdınız. Bu şekilde iki kere memory
ayırmış oluyorsunuz ki ikinci satırda da ilk yaptığınızın adresini yok
kaybediyorsunuz.

Sanırım buradaki ilk satır gereksiz.

>
> printf("c :%p\n",c);
>
> free(c);
>
> }
>
> deneme fonksiyonunun işaret ettiği adresi c pointına geçtim tamam ama
> benim kafama asıl takılan
> free(c) yazdığımda
>
> 1: deneme fonksiyonundaki b point adreside mi özgür bırakılacak?

Hayır. O adres b = a; işlemi ile unutuldu.

> 2: ben free(c) etmeme rağmen b pointı halen aynı adresini koruyor,

Evet çünkü free ettiğiniz hafıza geçersiz. Bu durumda programın
çalışmaya devam etmesi bile yeterince güzel.

> demekki free(c) ile b free olmuyor diye düşündüm ama ne kadar doğru
> bilemiyorum.
> 3: programı kapatıp açmama rağmen her seferinde aynı adresi göstermeleri
> normal mi?

Normal.

> 4: eğer free(c) yazdığımda b free olmuyorsa fonksiyondan ayırdığım belek
> alanını fnksiyondan cıktıktan sonra nasıl free edebilirim?

Tam olarak yapmak istediğinizi anlamadım. Galiba bu tarz birşey
kullacaksınız.

int main()
{
     char *str = deneme("0123456789\0");

     printf("%d\n", strlen(str));
     printf("%s\n", str);

     /* Artık işimiz bitti. Free edebiliriz. Free ile boşaltıcağımız
      * memory daha önce mutlaka malloc( ya da arkadaşları) tarafından
      * ayrılmış olmalı
      */
     free(str);

     return 0;

}

char* deneme(char *str)
{
        /* Bize geçilen adresin içinde oynamak istediğimiz karakter katarı olsun.
         * str'in sonunda NULL karater olduğunu varsayalım
         */
        
        /* Diyelim ki karakter katarını dört kere tekrar etmek istiyoruz.
Karakterin
         * sonuna NULL karakter koymak için fazladan bir tane yer daha lazım
         */
        char *ptr = (char *)malloc(strlen(str) * 4 + 1);
        
        if( ptr == NULL)
                return NULL;
                
        strncpy(ptr, str, strlen(str));
        strncpy(ptr + strlen(str), str, strlen(str));
        strncpy(ptr + 2 * strlen(str), str, strlen(str));
        strcpy(ptr + 3 * strlen(str), str);
        
        return ptr;
}

Saygılarımla
Yusuf Caglar Akyuz
_______________________________________________
Linux-programlama mailing list
Linux-programlama@liste.linux.org.tr
http://liste.linux.org.tr/mailman/listinfo/linux-programlama


New Message Reply About this list Date view Thread view Subject view Author view Attachment view

---------

Bu arsiv hypermail 2.1.2 tarafindan uretilmistir.