User Tag List

1. Sayfa - Toplam 2 Sayfa var 12 SonuncuSonuncu
Gösterilen sonuçlar: 1 ile 10 ve 20

C Dilinde Dinamik String Dönen Bir Fonksiyon Oluşturmak

Programlama forumunda C Dilinde Dinamik String Dönen Bir Fonksiyon Oluşturmak konusunu incelemektesiniz.

Kod: char *giveunderline(char text[]) { char *temp=(char*)malloc(1*sizeof(char)); temp[0]='\n'; strcat(temp,text); strcat(temp,"\n"); for(int i=0; i<strlen(text); i++) { strcat(temp,"-"); } strcat(temp,"\n"); return temp; } Arkadaşlar basit bir örnek yazdım. Buradaki fonksiyon parametre olarak ...

  1. #1
    Ben Kenobi - ait Kullanıcı Resmi (Avatar)
    Üyelik tarihi
    Nov 2011
    Mesajlar
    720

    Standart C Dilinde Dinamik String Dönen Bir Fonksiyon Oluşturmak

    Kod:
    char *giveunderline(char text[])
    {
        char *temp=(char*)malloc(1*sizeof(char));
        temp[0]='\n';
        strcat(temp,text);
        strcat(temp,"\n");
        for(int i=0; i<strlen(text); i++)
        {
            strcat(temp,"-");
        }
        strcat(temp,"\n");
        return temp;
    }
    Arkadaşlar basit bir örnek yazdım.
    Buradaki fonksiyon parametre olarak string alıp bize başka bir string veriyor
    Görüldüğü üzere temp isimli bir string fonksiyona gönderilen text'in uzunluğu bilinmediği için dinamik olarak ayrılmış.
    Ancak bir sorun var
    Fonksiyon temp'i döndürdüğü için dinamik olarak ayrılmış bu bellek free olamıyor ve memory leak hatalarına neden oluyor.
    Free'yi return'den önce yapsam fonksiyon boş dönderiyor.
    Free'yi return'den sonra yapsam işe yaramıyor.
    Yardımlarınızı bekliyorum, saygılar

  2. #2

    Üyelik tarihi
    Oct 2010
    Mesajlar
    39

    Standart

    char temp[512];
    char *giveunderline(char text[])
    {
    int leng = 0, i = 0;
    leng = strlen(text);
    memset(temp,0,sizeof(temp));
    if(leng > 0 && leng < 512)
    {
    temp[0]='\n';
    strcat(temp,text);
    strcat(temp,"\n");
    for(i=0; i<leng; i++)
    strcat(temp,"-");
    strcat(temp,"\n");
    }
    return temp;
    }

    denemedim ama bu iş görür sanırsam
    Ben Kenobi bunu beğendi.

  3. #3
    Ben Kenobi - ait Kullanıcı Resmi (Avatar)
    Üyelik tarihi
    Nov 2011
    Mesajlar
    720

    Standart

    iyi de hocam temp'e statik değer verdikten sonra anlamı ne ki?
    memset ne işe yarıyor anlamadım ama statik değer verdikten sonra böyle de yapabiliriz.

    Kod:
    char *giveunderline(char text[])
    {
        char temp[512];
        temp[0]='\n';
        strcat(temp,text);
        strcat(temp,"\n");
        for(int i=0; i<strlen(text); i++)
        {
            strcat(temp,"-");
        }
        strcat(temp,"\n");
        return temp;
    }

  4. #4

    Üyelik tarihi
    Oct 2011
    Mesajlar
    32

    Standart

    Selam arkadaslar;

    Alıntı Ben Kenobi Nickli Üyeden Alıntı Mesajı göster
    iyi de hocam temp'e statik değer verdikten sonra anlamı ne ki?
    memset ne işe yarıyor anlamadım ama statik değer verdikten sonra böyle de yapabiliriz.

    Kod:
    char *giveunderline(char text[])
    {
        char temp[512];
        temp[0]='\n';
        strcat(temp,text);
        strcat(temp,"\n");
        for(int i=0; i<strlen(text); i++)
        {
            strcat(temp,"-");
        }
        strcat(temp,"\n");
        return temp;
    }
    yukaridaki kod calismaz, cunku temp dizini fonksiyon icerisinde tanimlanmis, fonksiyondan ciktiktan sonra bu bellek alaninin icerisinde ne olacagi belirsizdir. temp sadece buradaki temp degiskeninin adresini icerir ki buda fonksiyonun stack alaninda bir yerleri gosterir. Longh0rn un soyledigi yontem kullanilabilir, memset ile arrayin icerisindeki degerleri sifirliyor ama buda benim cok tercih edecegim bir yontem degildir cunku a) bu durumda sadece tek bir temp degiskeni olabilir. Oysa bir dongude bu fonksiyon 10larca kez calistirilmak ve onlarca kez donen string degerleri ayni anda hafizada tutulmak istenebilir. b) temp boyutu oncededen belli oldugunu icin limitli bir cozum sunar.

    Bence su sekilde yapmak daha dogrudur:
    Kod:
    char *bana_string_ver(char *paramatreler) 
    {
    char *donen_dizi;
    
    donen_dizi = (char *) malloc(512); //512 yi rastgele verdim, fonksion icerisinde ne kadar alan ayrilmasi gerektigi hesaplanmali.
    /*
    fonksiyona ozel kodlar, parametreleri kullan, donen_diziyi degistir vs.
    */
    return donen_dizi;
    }
    
    int main()
    {
    char *temp;
    
    temp = bana_string_ver("string paramatre");
    
    /* temp i kullan diger kodlar*/
    
    free(temp); //memory leak sorunu cozuldu. 
    }
    Biraz fazla yazdim ama sonuc olarak, return icin allocate edilmis bir alan o fonksiyon icerisinde degil, disinda bu degiskenle isin bittiginda free edilir ve memory leak olmaz.

    kolay gelsin
    Ben Kenobi bunu beğendi.

  5. #5
    Ben Kenobi - ait Kullanıcı Resmi (Avatar)
    Üyelik tarihi
    Nov 2011
    Mesajlar
    720

    Standart

    Alıntı sithlord Nickli Üyeden Alıntı Mesajı göster
    Selam arkadaslar;



    yukaridaki kod calismaz, cunku temp dizini fonksiyon icerisinde tanimlanmis, fonksiyondan ciktiktan sonra bu bellek alaninin icerisinde ne olacagi belirsizdir. temp sadece buradaki temp degiskeninin adresini icerir ki buda fonksiyonun stack alaninda bir yerleri gosterir. Longh0rn un soyledigi yontem kullanilabilir, memset ile arrayin icerisindeki degerleri sifirliyor ama buda benim cok tercih edecegim bir yontem degildir cunku a) bu durumda sadece tek bir temp degiskeni olabilir. Oysa bir dongude bu fonksiyon 10larca kez calistirilmak ve onlarca kez donen string degerleri ayni anda hafizada tutulmak istenebilir. b) temp boyutu oncededen belli oldugunu icin limitli bir cozum sunar.

    Bence su sekilde yapmak daha dogrudur:
    Kod:
    char *bana_string_ver(char *paramatreler) 
    {
    char *donen_dizi;
    
    donen_dizi = (char *) malloc(512); //512 yi rastgele verdim, fonksion icerisinde ne kadar alan ayrilmasi gerektigi hesaplanmali.
    /*
    fonksiyona ozel kodlar, parametreleri kullan, donen_diziyi degistir vs.
    */
    return donen_dizi;
    }
    
    int main()
    {
    char *temp;
    
    temp = bana_string_ver("string paramatre");
    
    /* temp i kullan diger kodlar*/
    
    free(temp); //memory leak sorunu cozuldu. 
    }
    Biraz fazla yazdim ama sonuc olarak, return icin allocate edilmis bir alan o fonksiyon icerisinde degil, disinda bu degiskenle isin bittiginda free edilir ve memory leak olmaz.

    kolay gelsin
    hocam benim yazdığım kodda nasıl bir sorun var anlamadım.
    üstteki verdiğim iki kod da çalışıyor.
    ancak birincisi takdir edersiniz ki memory leak hatalarına neden oluyor aynı fonksiyon birden fazla kez çağrılınca.
    ikincisi ise kısıtlı bir çözüm sunuyor, işin kolayına kaçmak oluyor.
    sizin çözümünüzü denemedim ama işe yaracağını sanıyorum.
    ben ise bu fonksiyonu nasıl kullandığıma baktım şu şekilde kullanmışım.

    Kod:
    printf(giveunderline("deneme"));
    şimdi burda nasıl free yapacaz

    --- Mesaj Güncellendi ---

    evet bu arada ikinci örnekte yanlış çalışıyormuş.
    Kod:
    temp[0]='\0';
    yapmak lazım.

    --- Mesaj Güncellendi ---

    Şöyle birşey yazdım çalışıyor gibi ama.
    Nasıl çalıştığını ben de anlamadım

    Ben sanırım malloc veya pointer konusunda temelde birşeyi yanlış biliyorum

    Kod:
    char *giveunderline(char *text)
    {
        char *temp=(char*)malloc(1*sizeof(char));
        if(temp!=NULL)
        {
            free(temp);
        }
        temp[0]='\0';
        strcat(temp,"\n");
        strcat(temp,text);
        strcat(temp,"\n");
        for(int i=0; i<strlen(text); i++)
        {
            strcat(temp,"-");
        }
        strcat(temp,"\n");
        return temp;
    }
    Mesela main'e şunu koymazsam çalışmıyor o da garip.
    Kod:
    setlocale(LC_ALL,"");
    fonksiyonun doğru çalışıp çalışmadığını kontrol etmek için sonsuz while döngüsünde 1 dakika boyunca çalıştırdım birşey çıkmadı.
    normalde ikinci çağrılışta direk kapanıyordu program.
    ama gerçekten öylesine yazmıştım şimdi ciddi biçimde düşünce nasıl çalıştığını anlayamıyorum
    Konu Ben Kenobi tarafından (30-01-2012 Saat 15:45 ) değiştirilmiştir.

  6. #6

    Üyelik tarihi
    Dec 2010
    Mesajlar
    8

    Standart

    char *temp=(char*)malloc(1*sizeof(char));

    Bu kadar yer leak olsa ne olur, sadece 1 bayt istiyorsun yetecek mi? Ayrıca dönüştürme tipi (char) olmalı, (char*) değil.

    Bu gibi işlemlerde hem girdi hemde çıktı dışardan verilmeli. Standart string fonksiyonlarına bakarsanız görürsünüz.

    void changeString(char *dest, const char *source)
    {
    //dest üzerinde işlem yap
    }

    main()
    char str[] = "Bla bla...";
    char sonuc[40];
    changeString(sonuc, str);

    Doğru olan çağırıcının bellekten sorumlu olması, istisnalar olabilir tabi. Şimdi fonksiyonu istediğin kadar çağır farketmez.
    Ben Kenobi bunu beğendi.

  7. #7
    Ben Kenobi - ait Kullanıcı Resmi (Avatar)
    Üyelik tarihi
    Nov 2011
    Mesajlar
    720

    Standart

    hocam diyorum ya.
    ya benim bilgi eksikliğim var.
    ya da bu işte gariplik var
    ben 1 bayt yer ayırıyorum güya malloc'a göre.
    ama istediğim kadar ekliyorum hiçbir sıkıntı çıkmıyor.
    dosya işlemlerinde de öyle.
    dosyayı string olarak okuturken yine char pointer atayıp malloc'a tek baytlık yer ayırıyorum
    sonra her okunulan karakteri bu char pointer'ına ekliyorum
    en sonunda char'a bakıyorum ki bütün text üzerindeki string'i almış

  8. #8

    Üyelik tarihi
    Oct 2011
    Mesajlar
    32

    Standart

    Selamlar;

    Simdi sirasiyla gidelim;

    1-
    [COLOR=#333333]printf(giveunderline("deneme")) seklinde cagirman dogru olmaz- sanirim printf("%s",giveunderline("deneme")); demek istedin - cunku sen fonksiyonun icerisinde bellek ayiriyorsun ve daha sonra bu ayirdigin bellek adresinin ne oldugunu printf e gonderiyorsun, printf bunu kullanir ama artik senin bu adrese ulasma sansin kalmaz, java yada c# olsaydi , havada kalan objeler GC tarafindan toplanirdi ama C de bunu senin yapman lazim. yani kisaca soyle

    char *temp = giveunderline(deneme);
    printf("%s",temp);
    free(temp);
    seklinde yazarsan sorun kalmaz.

    2- [/COLOR]temp[0]='\0'; yapman strcat icin onemli, strcpy ile calissan bunada gerek kalmaz.
    3-
    setlocale(LC_ALL,""); tamamaen alakasiz bir fonksiyon, neden etkliyor tahmin etmek zor.
    4-Amenofis demiski
    char *temp=(char*)malloc(1*sizeof(char)); yerine (char) olmali, hayir dogrusu senin yaptigin gibi (char *) olmali, malloc her zaman adres dondurur.
    5-demissin ki "
    ben 1 bayt yer ayırıyorum güya malloc'a göre.ama istediğim kadar ekliyorum hiçbir sıkıntı çıkmıyor." Aslinda sorun cikiyor. Senin sorunun memory leack degil senin sorunun baska degisken uzerine kaydetme, stack overflow yada bunun gibi seyler , soyleki sen 1 bayt yer ayiriyorsun ama 10 bayt karakter yaziyorsun uzerine, ekstra karakterler baska seylerin uzerine yaziliyor ve eger stack yada buffer sinirlarinin disina cikinca bilinmekyen durumlar olusuyor demektir. Ihtiyacain oldugu kadar bellekte yer ayirman lazim. Isaretciler konusuna yeniden bakmani tavsiye ederim.

    Kolay gelsin
    Ben Kenobi bunu beğendi.

  9. #9

    Üyelik tarihi
    Dec 2010
    Mesajlar
    8

    Standart

    Önceki mesajımda dönüştürme tipini yanlış söylemişim, aklıma neden öyle geldiyse. Kusura bakmayın.

    @Ben Kenobi

    http://forum.shiftdelete.net/program...-gonderme.html (C Dilinde Parametre Olarak String İçinde String Gönderme)
    Bu konuda bir açıklama yapmıştım son mesajda. Keşke okusaydın.

    Konunun önemine binaen bir de örnek ekliyorum. Bunu denesen çok iyi olur. Değişkenimizin bizden habersiz nasıl değişebileceğini gösteriyor.

    Eğer hata verirse SD sabitini biraz düşür. ptr[SD] == 0 olmazsa sabiti biraz arttır.

    Kod:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define SD 30
    
    int main()
    {
        char *ptr = (char*) malloc(4);  // 4 bayt yer iste
        ptr[SD] = 100;  // Sınır dışında bir bölgeye 100 yaz
        printf("%d\n", ptr[SD]);    // "100"
        
        char *ptr2 = (char*) calloc(50, 1); // Biraz daha yer al ve burayı sıfırla
        printf("%d\n", ptr[SD]);    // Önceki yer 0 oldu
        return 0;
    }
    Ben Kenobi bunu beğendi.

  10. #10
    Ben Kenobi - ait Kullanıcı Resmi (Avatar)
    Üyelik tarihi
    Nov 2011
    Mesajlar
    720

    Standart

    Alıntı sithlord Nickli Üyeden Alıntı Mesajı göster
    Selamlar;

    Simdi sirasiyla gidelim;

    1-
    [COLOR=#333333]printf(giveunderline("deneme")) seklinde cagirman dogru olmaz- sanirim printf("%s",giveunderline("deneme")); demek istedin - cunku sen fonksiyonun icerisinde bellek ayiriyorsun ve daha sonra bu ayirdigin bellek adresinin ne oldugunu printf e gonderiyorsun, printf bunu kullanir ama artik senin bu adrese ulasma sansin kalmaz, java yada c# olsaydi , havada kalan objeler GC tarafindan toplanirdi ama C de bunu senin yapman lazim. yani kisaca soyle

    char *temp = giveunderline(deneme);
    printf("%s",temp);
    free(temp);
    seklinde yazarsan sorun kalmaz.

    2- [/COLOR]temp[0]='\0'; yapman strcat icin onemli, strcpy ile calissan bunada gerek kalmaz.
    3-
    setlocale(LC_ALL,""); tamamaen alakasiz bir fonksiyon, neden etkliyor tahmin etmek zor.
    4-Amenofis demiski
    char *temp=(char*)malloc(1*sizeof(char)); yerine (char) olmali, hayir dogrusu senin yaptigin gibi (char *) olmali, malloc her zaman adres dondurur.
    5-demissin ki "
    ben 1 bayt yer ayırıyorum güya malloc'a göre.ama istediğim kadar ekliyorum hiçbir sıkıntı çıkmıyor." Aslinda sorun cikiyor. Senin sorunun memory leack degil senin sorunun baska degisken uzerine kaydetme, stack overflow yada bunun gibi seyler , soyleki sen 1 bayt yer ayiriyorsun ama 10 bayt karakter yaziyorsun uzerine, ekstra karakterler baska seylerin uzerine yaziliyor ve eger stack yada buffer sinirlarinin disina cikinca bilinmekyen durumlar olusuyor demektir. Ihtiyacain oldugu kadar bellekte yer ayirman lazim. Isaretciler konusuna yeniden bakmani tavsiye ederim.

    Kolay gelsin
    cevaplarınız için çok teşekkür ederim sayın üstad
    ben de birkaç bildiğimi karalayım.
    öncelikle böyle bir şey yanlış değil
    1-printf içerisine parantez koymadan direkt string'in ismini yazarsak hatta daha dolaylı olarak string döndüren bir fonksiyon koyarsak yapabiliriz.
    bunu C kitabında görmüştüm zaten.
    ama siz yanlış diyerek neyi kastediyorsunuz anlaşılmıyor, acaba önerilmiyor tarzında mı demek istediniz.
    içerideki değerler havada kalmıyor stdout içerisinde hepsi siz de takdir edersiniz.
    ama stdin ve stdout ile uğraşmak şu an benim harcım değil
    fclose(stdout) diyip yeniden stdout'u açmayı düşündüysem bile daha sonra bir fonksiyonu farklı iki fonksiyonla kullanma zorunluluğu esnekliği ortadan kaldırdığı için vazgeçtim

    2-strcpy yanlış hatırlamıyorsam yine buffer sınırı koyuyor.
    ben zaten karakter sınırını bilmiyorum ve text'in içerisine yine text'i ekliyorum.
    ben sınır koymaktan yana değilim, yoksa sınır koysaydım bunları tartışıyor olmazdık pointer yerine array yapardım olur biterdi

    3-Çok ilginç bir durum hocam setlocale olayı sanırım benim bilgisayar ile alakalı, çünkü hem mingw hem visual c++ hem de intel'in compiler'ıyla denedim sonuç değişmedi.

    4-Malloc olayına benim kafa basmadığı için yabancı bir forum sitesinden aldım adamlar sayfalarca tartışmış daha sonra en güzel malloc kullanımının o şekilde olduğuna karar vermişler sizin dediğiniz gibi.

    5-Üstad stack overflow bilmiyorum ama araştırayım. Ancak ne kadar yüksek verirsem vereyim sonuçta kullanıcı benim verdiğim sınırdan daha fazla karakter girerse her zaman bu stack overlow veya herneyse ihtimali var demektir. Üstad herkes birşeyler söylüyor ama kimse doğru düzgün anlatmıyor. Biliyorsanız zamanınız varsa anlatın paylaşın lütfen



    @
    Amenofis üstad ayıp ettiniz ben soru soruyorum siz de lütfetmişsiniz mesaj atmışsınız ve ben bunu okumaz olur muyum
    Sizin verdiğiniz örneği denedim.
    SD sabitini 3'e de indirsem 300'e de çıkarsam bana hep iki kez 100 verdi.
    Mingw, visual c++ ve intel'in compiler'larının üçüyle de denedim
    Siz kendi bilgisayarınızda denemiş miydiniz?
    Acaba Windows'un 64 bit falan olması etkileyebilir mi?
    Diyorum ya bir gariplik var

Konu Bilgileri

Bu konuyu görüntüleyenler

Şu an 1 kullanıcı var. (0 üye ve 1 konuk)

Benzer Konular

  1. Cevaplar: 6
    Son Mesaj: 28-01-2012, 22:14
  2. Cevaplar: 41
    Son Mesaj: 04-01-2012, 01:04
  3. Cevaplar: 10
    Son Mesaj: 12-12-2011, 21:58
  4. Cevaplar: 10
    Son Mesaj: 22-08-2010, 22:06
  5. Bir hata varmı acaba?
    tonce - forum Forum Hakkında
    Cevaplar: 38
    Son Mesaj: 05-02-2008, 21:06

Yetkileriniz

  • Konu Acma Yetkiniz Yok
  • Cevap Yazma Yetkiniz Yok
  • Eklenti Yükleme Yetkiniz Yok
  • Mesajınızı Değiştirme Yetkiniz Yok
  •  

vBulletin Optimisation by vB Optimise.