User Tag List
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 ...
-
30-01-2012 01:04 #1
C Dilinde Dinamik String Dönen Bir Fonksiyon Oluşturmak
Arkadaşlar basit bir örnek yazdım.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; }
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
-
30-01-2012 01:49 #2
- Üyelik tarihi
- Oct 2010
- Mesajlar
- 39
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
-
30-01-2012 10:50 #3
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; }
-
30-01-2012 11:47 #4
- Üyelik tarihi
- Oct 2011
- Mesajlar
- 32
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:
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.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. }
kolay gelsin
-
30-01-2012 15:42 #5
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.
şimdi burda nasıl free yapacazKod:printf(giveunderline("deneme"));
--- Mesaj Güncellendi ---
evet bu arada ikinci örnekte yanlış çalışıyormuş.
yapmak lazım.Kod:temp[0]='\0';
--- 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
Mesela main'e şunu koymazsam çalışmıyor o da garip.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; }
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ı.Kod:setlocale(LC_ALL,"");
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.
-
30-01-2012 16:42 #6
- Üyelik tarihi
- Dec 2010
- Mesajlar
- 8
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.
-
30-01-2012 16:49 #7
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ış
-
30-01-2012 19:39 #8
- Üyelik tarihi
- Oct 2011
- Mesajlar
- 32
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 soylechar *temp=(char*)malloc(1*sizeof(char)); yerine (char) olmali, hayir dogrusu senin yaptigin gibi (char *) olmali, malloc her zaman adres dondurur.
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
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
-
30-01-2012 20:01 #9
- Üyelik tarihi
- Dec 2010
- Mesajlar
- 8
Ö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; }
-
30-01-2012 21:07 #10
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
-
C Dilinde Parametre Olarak String İçinde String Gönderme
Ben Kenobi - forum ProgramlamaCevaplar: 6Son Mesaj: 28-01-2012, 22:14 -
C Dilinde Girilen String Değerine Göre Değişken Çağırmak
Ben Kenobi - forum ProgramlamaCevaplar: 41Son Mesaj: 04-01-2012, 01:04 -
C Dilinde Döngü Devam Ederken Bir Değeri Değiştirme
Ben Kenobi - forum ProgramlamaCevaplar: 10Son Mesaj: 12-12-2011, 21:58 -
Vb.net Sayısal Bir Textboxa "string" Değer Girilmemesi
SiberWorm - forum ProgramlamaCevaplar: 10Son Mesaj: 22-08-2010, 22:06 -
Bir hata varmı acaba?
tonce - forum Forum HakkındaCevaplar: 38Son Mesaj: 05-02-2008, 21:06


10Beğeni
Alıntı

Google + da paylaştığımızı facebookta otomatik paylaşan uygulama varsa banada lazım .
Google+ hesabımı Facebook ile...