PDA

Tam Sürümünü Görmek İçin : dinamik bellek problemi


rockistanblues
25/06/2008, 21:58
Merhaba arkadaşlar


bir proje üzerinde çalışmaktayım. C programlamada bir struct yapısına kayıt alıyorum. Fakat uygulamak istediğim dinamik bellek kontrolü girilen kayıt kadar olacak yani 15 lik kayıtsa 15 tanelik yer açılacak fakat dinamik bellek alınırken 5 tanesi boş geçerse program kendini kapatacak.

Benim yaptığım uygulama (daha doğrusu yapabildiğim) ise kayıt alırken en az 10 tane zorunluluğu.


#include<stdio.h>
#include<conio.h>
#include<stdlib.h>,
struct ev
{
int kisi;
int kiz;
int mkare;
}*p,*temp;
void main()
{
clrscr();
int n=15;
int zorunlu=10;
int kisitoplam=0;
int kiztoplam=0;
int mkaretoplam=0;
//int sayac=0;
do
{
p=(struct ev*) malloc (sizeof(struct ev)*n);
}while(p=='\0');
temp=p;
int i=0;
do{
printf("%d. evdeki kisi sayisini girin:",i+1); scanf("%d",&p->kisi);
printf("%d. evdeki kiz sayisini girin:",i+1); scanf("%d",&p->kiz);
printf("%d. evin metrekaresini girin:",i+1); scanf("%d",&p->mkare);
printf("\n Veri girmeye devam etmek i‡in 1 e basiniz");
int bas;
scanf("%d",&bas);
if(bas!=1 && i<=zorunlu)
{
printf("En az %d kayit girmek zorundasiniz.",zorunlu);

}
if(bas!=1 &&i>=zorunlu)
{
break;
}
i++;
p++;
}while(i<n);
p=temp;


for(i=0;i<n;i++,p++)
{
printf("\n %d. kisi: %d",i+1,p->kisi);
printf("\n %d. kiz:%d",i+1,p->kiz);
printf("\n %d. mkare:%d",i+1,p->mkare);
kisitoplam=kisitoplam+p->kisi;
kiztoplam=kiztoplam+p->kiz;
mkaretoplam=mkaretoplam+p->mkare;
}
printf("\n Ev basina dusen kisi ortalamasi %d / %d : %d",n,kisitoplam,n/kisitoplam);
printf("\n Ev basina dusen kiz ortalamasi %d / %d : %d",n,kiztoplam,n/kiztoplam);
printf("\n Ev basina dusen metrekare ortalamasi %d / %d : %d",n,mkaretoplam,n/mkaretoplam);
getch();
}


yardım, fikir ve alternatif görüşlerinizi beklemekteyim.

iyi çalışmalar.


acehreli
26/06/2008, 00:14
Soylediklerinden bir sey anlamadim. Ama koda bakinca nerede yanlis yaptigini goruyorum. Sanki birden fazla cumleyi aralarina nokta koymadan yazmissin gibi. :)

Herhangi bir bellek bir dizi gibi kullanilabilir. p->kisi yazdigin zaman, bu dizinin en basindaki 'ev'in 'kisi'sinden bahsediyorsun. Halbuki dOngU ilerledikce hep bir sonraki 'ev' ile ilgilenmen gerekiyor:

scanf("%d",&p[i].kisi);

Ali

Not: 'main'in 'int' dOndurmesi sarttir. 'void main' yerine 'int main' yazman gerekiyor.

Coldplay
26/06/2008, 11:24
Not: 'main'in 'int' dOndurmesi sarttir. 'void main' yerine 'int main' yazman gerekiyor.

acehreli beye katilmiyorum. Main her zaman int geri vermek zorunda degil. Bu kullanilan compiler'a göre fark edebilir. Linux tabanli (gcc gibi) cogu compiler int main() beklerken mesela borland'da veya microsoft visual studio'da void main() de kullanabilirsiniz.

quasimodo
26/06/2008, 13:57
acehreli beye katilmiyorum. Main her zaman int geri vermek zorunda degil. Bu kullanilan compiler'a göre fark edebilir. Linux tabanli (gcc gibi) cogu compiler int main() beklerken mesela borland'da veya microsoft visual studio'da void main() de kullanabilirsiniz.

Kullanabilirsin ama standart boyle diyor.

Coldplay
26/06/2008, 15:27
quasimodo, ben standarttan ba$ka türlü iyor demedim ki zaten. Bu bir $art degil dedim. Compiler void main kabul ettikten sonra illa ki int main kullamak $art degildir dedim. Zaten void main de kullansan compiler kendisi rastgele bir int genere edip onu geri verecektir.

Not: 'main'in 'int' dOndurmesi sarttir. 'void main' yerine 'int main' yazman gerekiyor.Herhangi bir skript programindan veya batch programindan bu C/C++ programi cagrilmadiktan sonra main int vermis void vermis bir önemi yok. Sonucta int main de tanimlasan return 0; diyorsun. Ve bu degeri hicbir program okumuyor.

Main'i int olarak tanimlamanin amaci hata olustugunda sifirdan büyük degerlerle programin terk edilmesidir. Ki bu da eger bu C/C++ programini bir skript programindan veya batch programindan cagirdiysan i$ine yarar. O zaman programin geri verdigi degere göre skript yada batch programinda hatayi ele alip mesela kullaniciyi bilgilendirebilirsin. Ama böyle bir durumun söz konusu olmadigi zamanlarda -eger compiler de kabul ediyorsa- asagidaki iki secenekten hangisinin kullanildigi önemsiz.

void main()
{
...
}


int main()
{
...
return 0;
}

rockistanblues
26/06/2008, 17:49
Soylediklerinden bir sey anlamadim. Ama koda bakinca nerede yanlis yaptigini goruyorum. Sanki birden fazla cumleyi aralarina nokta koymadan yazmissin gibi. :)

Herhangi bir bellek bir dizi gibi kullanilabilir. p->kisi yazdigin zaman, bu dizinin en basindaki 'ev'in 'kisi'sinden bahsediyorsun. Halbuki dOngU ilerledikce hep bir sonraki 'ev' ile ilgilenmen gerekiyor:

scanf("%d",&p[i].kisi);

Ali

Not: 'main'in 'int' dOndurmesi sarttir. 'void main' yerine 'int main' yazman gerekiyor.
anlatmak istediklerim gayet açık aslında, dinamik bellek alınırken boş geçme kontrolünü yaptırmak istiyordum, hallettim.

@ColdPlay ilgin için teşekkürler.

Şöyle halletim problemimi;


do
{
p=(struct ev*) malloc (sizeof(struct ev)*n);
sayac++;
}while(p=='\0' || sayac==5);
if(sayac==5)
{
printf("Program kapatiliyor...");
}

acehreli
26/06/2008, 19:03
Coldplay, hangi anlamda katilmiyorsun acaba. Standardi yazan grupta olsak ve ben int'in gerekliligini savunuyor olsam senin katilmamani anlarim ama olan olmus, startart yazilmis bir kere...

'void main'e izin veren derleyiciler o programi C veya C++'in bir diyalekti olarak derliyorlar demektir. Bunu gormek cok acik: C ve C++, main'in int dOndUrmesini sart kosar.

Bu arada, "sart" sozcugunu ben yakistirmiyorum: Standart; sart olan, derleyiciye birakilan, ve tanimlanmadan birakilan kurallar ve davranislar belirler. main'in int dOndUrmesi derleyiciye birakilan bir davranis degildir.

Herkes istedigi gibi yazabilir tabii ki. Oyle yapinca da genele acik bir forumda dogrusu ile karsilasabilirler.

rockistanblues, anlatmak istediklerin acik olsaydi anlamayanlar olmazdi herhalde. Yazdiklarini bir kere daha okursan birden fazla cumleyi birbirlerine karisik olarak yazdigini goreceksin:

"Fakat uygulamak istediğim dinamik bellek kontrolü girilen kayıt kadar olacak yani 15 lik kayıtsa 15 tanelik yer açılacak fakat dinamik bellek alınırken 5 tanesi boş geçerse program kendini kapatacak."

Ali

quasimodo
26/06/2008, 19:23
Bakiniz -> ISO/IEC 9899 : 5.1.2.2.1

Coldplay
26/06/2008, 22:58
Zaten void main de kullansan compiler kendisi rastgele bir int genere edip onu geri verecektir.Ya ben anlatamiyorum ya da siz Californiya'da Türkceyi unuttunuz. Ben yukarida da görüldügü gibi void main'e izin veren compiler'lar zaten kendileri arka planda bir random int üretip onu geri verirler dedim. Eger compiler bana bu rahatligi sunuyorsa bunu kullanabilirim.

Standarttan bakip ban söylemek yerine keske benim yaptigim gibi bun main'den gelen int degerinin nerelerde ne ise yarayabilecegini anlatsaydiniz.

acehreli
26/06/2008, 23:16
Coldplay, dogal olarak yazdiklarinin yalnizca bu forumu ilgilendiren bolumlerine yanit verecegim.

Derleyicinin rastgele bir dOnUs degeri urettigini yanlis bir kaynaktan ogrenmis olmalisin. Yanlis da kurgulamis olabilirsin.

main'den dOnen degerin nerelerde kullanilacagini sen zaten anlattin; tekrarlamaya gerek oldugunu dusunmuyorum.

Ali

quasimodo
26/06/2008, 23:33
Benim anlamadigim nokta geri donus degeri yerine void yazdigim fonksiyondan kim ne hakla bir '1' degeri donduruyor ki?

Coldplay
27/06/2008, 09:46
Acehreli bey amacim tartismak degil sadece bilgi alisverisinde bulunmak, bu yüzden umarim yanlis anlamaya neden olmamisimdir.

Tabi ki standartlari biz yazmadik yanlis anladigimiz ya da bilmedigimiz yerler olabilir. Asagida MSDN'den Visual C++'ta main fonksiyonuyla ilgili tanimlamayi bulabileceginiz bir link veriyorum. En basta dedigim gibi bazi compiler'lar kendi standartlarinda void main kullanmaya izin veriyorlar. Bu linkte de Microsoft kendi sistemlerinde kullanicinin void main kullanabilecegini belirtmis ve tabi ki standart kullanimin int main oldugu da belirtiliyor. Ben de zaten standart söyle ya da böyle diyor dememistim sadece bazi compiler'lar bunu mümkün kiliyor, eger soruyu soran rockistanblues arkada$ öyle bir compiler kullaniyorsa illa ki main'i degistirmesine gerek yok demistim.

http://msdn.microsoft.com/de-de/library/6wd819wh.aspx

Bu da yukaridakin linkten konuyla ilgili alinti:
Alternately, the main and wmain functions can be declared as returning void (no return value). If you declare main or wmain as returning void, you cannot return an exit code to the parent process or operating system using a return (http://msdn.microsoft.com/de-de/library/f6s6c85a.aspx) statement; to return an exit code when main or wmain is declared as void, you must use the exit (http://msdn.microsoft.com/de-de/library/k9dcesdd.aspx) function.Saygilarimla...

shurzan
29/06/2008, 03:47
Merhaba coldplay;
Bu tartışmayı kimi zaman bu ve başka formlarda da görüyorum ve anlamıyorum bu muahalefet neden amaç standartı mı yıkmak yoksa C++ komitesinin bu kararının yanlış olduğunumu savunmak.

Ve Borland C++ ın main için void dönüşüne izin verdiğini belitmişsin bu yanlış bendeki BDS 2006 ve buna izin vermiyor. Yeni bir proje başlattığımda deleyicim bana aşağıdaki kodu üretiyor.
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
return 0;
}
//---------------------------------------------------------------------------

Ayrıca standartta olmamasına rağmen MS Visual C++ deleyicisinde içerik operatörü olarak ^ karakterinide içerik operatörü olarak kullanmaya izin veriyor.

İçerik operatörü olarak ^ kullanılmasına izin verilmesi ne kadar doğruysa main'in void döndürmesine izin verilmeside o kadar doğrudur ve bunu savunmakta o kadar doğrudur.

MS ve vs. standart dışı uygulamaya izin veren derleyici üreticiler acaba bir sonraki versiyonunda hangi karakteri başka amaç için kullacaklar veya dilin standartını bozacak ne abuk sabuk şey geliştirecekler acaba bu merak konusudur.

Standarta uymayanlar derleyici üreticilerin yeni versiyonlarını takip etmeli.

Coldplay
29/06/2008, 15:50
Shurzan,

bu konu benim icin hallolmustu, o yuzden aslinda cevap vermek istemiyorum. Zaten icerik arkadasin asil sordugu sorudan da sapti. Herkes istedigini kullansin, zaten ben de int main kullaniyorum, amacim muhalefet degil soru soran arkadaslari esasli bilgilendirmek. "Standartta öyle yaziyor öyle yap" yerine biraz daha aciklama yapilabilir. Arkadas alternatifleri bilsin istedik.

Hepinize iyi calismalar.