[ Predrag Damnjanovic @ 01.04.2002. 19:49 ] @
int main(void) {
char *a[5];
strcpy (a[0], "aaaaaaaa");
printf("%s\n", a[0]);
return 1;
}

Ovo radi perfektno!
Ali, ako char *a[5]; stavim kao globalnu promenljivu - program puca!
Nije do kompajlera, i u vc++ isto puca...
...a lepo se iskompajlira?
[ filmil @ 01.04.2002. 20:05 ] @
Citat:
zastita:
Ovo radi perfektno!


Program ti je neispravan.

char *a[5]

je, kao sto zna svako dete koje je procitalo neku knjigu o C-u, niz od 5 pointera na char od kojih svaki moze da pokazuje na neki string.

Ti medjutim ne alociras memoriju ni za jedan od tih 5 pointera, a sa strcpy kopiras string u memoriju na koju pokazuje a[0]. Kada je a lokalna promenljiva, prema standardu, pointeri uzimaju vrednosti jednake onome sto se zateklo na steku u to vreme, tako da pokazuju na proizvoljne lokacije.

Kada je a globalna promenljiva, svi pointeri iz niza a su inicijalizovani na NULL tako da strcpy puca uz SIGSEGV (Segmentation Fault). U slucaju kada je a na steku, samo si se slucajno izvukao bez greske i program ti naizgled radi.

Da bi program ispravno radio, moraces da alociras memoriju za a[0]:

Code:

a[0] = (char *) malloc( strlen( taj_string_sto_upisujes) + 1);
strcpy( a[0], taj_string_sto_upisujes);


poz.
[ Predrag Damnjanovic @ 01.04.2002. 20:10 ] @
Hvala
[ anatogen @ 02.04.2002. 01:38 ] @
Citat:
filmil:

U slucaju kada je a na steku, samo si se slucajno izvukao bez greske i program ti naizgled radi.



Mrzi me da probam ali posto pointer a[0] "dobija" proizvoljnu vrednost sa steka (tj. sta god je bilo na steku u to vreme kada je odvojen prostor za njega) zar je moguce da je ta vrednost bas neka adresa u dozvoljenom opsegu virt. adresa, odnosno zar ne bi skoro svaki put takav program popio SIGSEGV....
[ Dragi Tata @ 02.04.2002. 01:40 ] @
I ne zaboravi na

free (a[0]);

kad završiš sa tim stringom.
[ filmil @ 02.04.2002. 09:32 ] @
Citat:
anatogen:
dozvoljenom opsegu virt. adresa, odnosno zar ne bi skoro svaki put takav program popio SIGSEGV....


Ne znam zbog čega se provuče. Ako te ne mrzi da probaš, odvrti jednu sesiju sa GDB-om, stvari će valjda postati jasnije.

Dovoljno je recimo da pointer pokazuje negde na stek, u kom slučaju ga nikada nećeš uhvatiti ni za glavu ni za rep. Ali će zato, posle nekog vremena procedure koje si pozvao početi da se vraćaju na nepostojeće adrese.

poz.
[ Reljam @ 02.04.2002. 10:00 ] @
Citat:
Filmil:
Code:

a[0] = (char *) malloc( strlen( taj_string_sto_upisujes) + 1);
strcpy( a[0], taj_string_sto_upisujes);



je isto sto i

Code:

a[0] = strdup(taj_string_sto_upisujes);


I isto sledi free posle.
Mislim da je ova druga varijanta laksa-na-oci ;)
[ Predrag Damnjanovic @ 02.04.2002. 12:27 ] @
A sto se tice knjige, citao sam , al' pre 2 godine, i to sam uglavnom sintaksu gledao...
Posle sam neke tutorijale gledao, i to je sve.
Zato se ovoliko bulim sa C-om...
A ako vam merak da me zafrkavate, slobodno, ne ljutim se , jer stvarno ne znam mnogo C.
Ja sam do sada programirao u delphiju, a tamo nema ovakvih zajebancija sa float-ima i char-evima, tamo je sve 'easy to use', kao i ceo Windows
[ filmil @ 02.04.2002. 14:01 ] @
Citat:
zastita:
A ako vam merak da me zafrkavate, slobodno, ne ljutim se :), jer stvarno


Mislim da bi trebalo da zna da je skoro svako tvoje pitanje kao izvueno iz C FAQ-a. Hou da kaem, zbog toga izgleda kao da ovde pokuava da uradi jednu od sledee dve stvari:

1. Mrzi te da proita FAQ i vidi kako su ljudi reavali probleme koji te mue, pa ak i neke na koje tek treba da naleti.

ili

2. Proitao si C FAQ a dovoljno si zaludan da ide po stavkama i postavlja ih kao pitanja na forumu.

Dakle, vrlo lako moe da se zakljui da zafrkava narod po forumu pa se ne bih iznenadio da ti na tako neto ljudi uzvrate zafrkancijom.

A to se knjige tie, bez obzira da li si itao ili ne, ako ve misli da naui C i bude produktivan programer, uzmi kupi neku dobru C knjiicu. Znam da nije lako prvo pronai stvarno dobru knjigu a potom je i platiti jer jebiga kriza je i sve to, ali to je zaista jedini nain.

Ako dozvoljava da ti preporuim odlinu i jeftinu knjigu za uenje C-a onda je to knjiga Lasla Krausa, "Programski jezik C sa reenim zadacima" u izdanju Elektrotehnikog fakulteta u Beogradu koja se moe kupiti u skriptarnici ETF-a (izdaju je i neki poznati izdavai ali njih neu ovde da reklamiram :) ).

Znam da e neko odmah da mi skoi za vrat ali jo uvek sam ubeen da je po odnosu cena/performanse ovo knjiga koja stoji rame uz rame sa K&R-om kog nije ba jednostavno pronai u YU.

f.

[ Ivan Dimkovic @ 02.04.2002. 14:11 ] @
Zastita,

osim obaveznog cesljanja C-FAQ-a i neke dobre C knjige, savetujem ti da koristis i neki tool za nalazenje gresaka.

Na primer, ja sa Visual C++ koristim NuMega BoundsChecker - veruj mi, ako budes radio nesto glomaznije, greske se obavezno ponekad jave - bez obzira koliko si vest. A ovakve alatkice ti lepo kazu sta si propustio da uradis.

Naravno, ovakve alatke ti nece pomoci da otkrijes greske u algoritmu koji planiras da uradis, ali za ove greske sa alokacijom, pointerima, itd.. su dusu dale :)

A K&R mozes da nadjes u skriptarnici PMF-a, za nekih 100 din :)
[ anatogen @ 03.04.2002. 01:08 ] @
Citat:
filmil:
Ako dozvoljavaš da ti preporučim odličnu i jeftinu knjigu za učenje C-a onda je to knjiga Lasla Krausa, "Programski jezik C sa rešenim zadacima" u izdanju Elektrotehničkog fakulteta u Beogradu koja se može kupiti u skriptarnici ETF-a (izdaju je i neki poznati izdavači ali njih neću ovde da reklamiram :) ).

Znam da će neko odmah da mi skoči za vrat ali još uvek sam ubeđen da je po odnosu cena/performanse ovo knjiga koja stoji rame uz rame sa K kog nije baš jednostavno pronaći u YU.



Procitao sam obe te knjige i naravno izuzetno su korisne, pogotovo K&R :) ali i ako sam teski pocetnik mislim da znati C dobro podrazumeva mnogo vise od toga...

Na primer: poznavalje arhitekture racunara uopste (kako to sve radi) pa onda kernel i u sve vezi njega (pogotovo mm) pa kako izgleda taj nas C kod u asembleru (gde su koje promenjive sta je stack frame npr.) pa kako radi linkovanje staticko i dinamicko itd...


[ Ivan Dimkovic @ 03.04.2002. 01:24 ] @
To se uci na "Osnovama Programiranja" - Racunarstvo i Informatika, smer na PMF-u - ima knjiga po nasim knjizarama koje su udzbenici za ovo, gde se bas pocinje od arhitekture, preko osnova o programskim jezicima, informacija o kompajlerima, iterpretatorima.. pa onda tipovima podataka, strukturama...

osnovnim algoritimima... itd..

Ja se secam da sam u to vreme, za ispit uzeo "Programski Jezik PASCAL" od Tosica, samo zato sto je tu lepo objasnjeno bas to gore - kako taj isti profesor voli :)) Nema veze sto je PASCAL bio u pitanju, posto sam ja radio u C-u, principi su manje-vise isti - samo je sintaksa drugacija. Osnove su zajednicke.
[ masetrt @ 04.04.2002. 13:41 ] @
Ljudi zaboravite na malloc ,realloc i free od pojave c++ se koristi new i delete
tako da bi izgledalo:
char *str;
str=new char[5];
.
.
.
delete []str;
Dinamicki nizovi su bolji i imaju nekoliko nacina pristupa, new i delete su stabilniji (pogledaj bilo koju profi statistiku) od malloc i free
[ Ivan Dimkovic @ 04.04.2002. 13:57 ] @
Nisam te bas najbolje razumeo:

Citat:

Dinamicki nizovi su bolji i imaju nekoliko nacina pristupa, new i delete su stabilniji (pogledaj bilo koju profi statistiku) od malloc i free


U kom smislu stabilniji?

Mislis da je kod u kome se koriste new/delete umesto malloc/free statisticki stabilniji?

Ili mislis da su implementacije new/delete u kompajlerima stabilnije od malloc/free?

Ja ne vidim neku veliku razliku. Ja new/delete koristim za klase, a malloc/free za memorijske bafere, nizove, itd... Niko ti ne brani da koristis malloc/free u C++ kodu, tamo gde je to moguce.
[ Jovan Marjanovic @ 04.04.2002. 13:58 ] @
zasto bi uopste deklarisao a kao *a[5]

lepo deklarises kao **a i zavrsis posao. onda alociras koliko ti treba svega.
Isto tako mozes da napravis nesto ovako :

Code:

#define StrLenA(str)(strlen(str)+1)

char * StrNCopy(constant char  * str)
{
size_t duzina;
char *novistring;

if (str == NULL) str = "";
duzina = StrLenA(str);
novistring = malloc(duzina);
memcpy(novistring, str, duzina);

return novistring;
}

for (x=0;x<nesto;x++)
*a[x] = StrNCpy("nekistring");



mwahaha, morao sam malo da se izivljavam :
[ Jovan Marjanovic @ 04.04.2002. 14:01 ] @
naravno, kad zavrsis sa tom promenljivom moras da napravis free na sve elemente arraya, i da sve lepo pocistis iza sebe, ali u principu nije problem.

jos jedno pitanje, zasto bi ikada deklarisao bilo sta globalno ?
[ filmil @ 04.04.2002. 14:26 ] @
Citat:
Reljam:
je isto sto i
Code:

a[0] = strdup(taj_string_sto_upisujes);

Mislim da je ova druga varijanta laksa-na-oci ;)


Ovo je do sada najbolji i najjednostavniji savet. Tata, postavi ovo u FAQ ako te ne mrzi.

poz.
[ filmil @ 04.04.2002. 14:27 ] @
Citat:
blue:
mwahaha, morao sam malo da se izivljavam :


Iskreno se nadam da nisi bio ozbiljan kad si kucao ovo gore. :)

poz.
[ filmil @ 04.04.2002. 14:34 ] @
Citat:
blue:
jos jedno pitanje, zasto bi ikada deklarisao bilo sta globalno ?


Evo jedan odgovor iz prve ruke :)

C radi na svakojakom hardveru. Ako pišeš program recimo za mikrokontroler 8031, moraćeš da deklarišeš kao globalne promenljive memorijski mapirane periferijske registre. Pristup preko pointera ne ide zato što pointeri pokazuju na drugi 'memory space' (kod PC-ja, recimo, takva razlika ne postoji) pa se ne generišu neophodni signali za pristup eksternoj memoriji i tako dalje i tako bliže.

Naravno možeš da registre proglasiš za static ali onda moraš sve funkcije koje im pristupaju da potrpaš u isti modul a to opet malo zapetljava stvar.

Kod programa za PC-je si u pravu. Nema potrebe da se bilo šta globalizuje.

poz.
[ Jovan Marjanovic @ 04.04.2002. 14:52 ] @
Citat:
filmil:

Kod programa za PC-je si u pravu. Nema potrebe da se bilo šta globalizuje.

poz.



PC, UNIX, stagod. Nikad nisam pominjao mikrokontrolere, i moram da kazem da nikada nisam pisao nista slicno. niti sam imao prilike da pisem firmwere.

sto se tice gore navedenog primera, to je samo parcence implementacije unicode-a koju sam nekada davno pisao za unix. funkcija koju sam napisao je nullsafe, i ponekad threadsafe :)
[ masetrt @ 04.04.2002. 15:41 ] @
Citat:
Ivan Dimkovic:
Nisam te bas najbolje razumeo:

Citat:

Dinamicki nizovi su bolji i imaju nekoliko nacina pristupa, new i delete su stabilniji (pogledaj bilo koju profi statistiku) od malloc i free


U kom smislu stabilniji?

Mislis da je kod u kome se koriste new/delete umesto malloc/free statisticki stabilniji?

Ili mislis da su implementacije new/delete u kompajlerima stabilnije od malloc/free?

Ja ne vidim neku veliku razliku. Ja new/delete koristim za klase, a malloc/free za memorijske bafere, nizove, itd... Niko ti ne brani da koristis malloc/free u C++ kodu, tamo gde je to moguce.




Nisam ja izmislio da su new i delete stabilniji (u oba slucaja) to su preporuke Bjarnea Stroustrupa i drugih velikih imena c++ programiranja . Pravo da ti kazem ne znam zasto. Cuo sam da ima veze ako ti paralelno radi neki Java program(zbog Javinog garbage collectora), ali stvarno nisam siguran. A dinamicki niz nije sigurniji nego lepsi za rad primer char[5] i * char sta ako se javi potreba za 8 znakova??
[ masetrt @ 04.04.2002. 15:43 ] @
Citat:
blue:
zasto bi uopste deklarisao a kao *a[5]

lepo deklarises kao **a i zavrsis posao. onda alociras koliko ti treba svega.
Isto tako mozes da napravis nesto ovako :

Code:

#define StrLenA(str)(strlen(str)+1)

char * StrNCopy(constant char  * str)
{
size_t duzina;
char *novistring;

if (str == NULL) str = "";
duzina = StrLenA(str);
novistring = malloc(duzina);
memcpy(novistring, str, duzina);

return novistring;
}

for (x=0;x<nesto;x++)
*a[x] = StrNCpy("nekistring");




Izvini meni ovo ni malo nije normalno
[ filmil @ 04.04.2002. 15:44 ] @
Citat:
blue:
PC, UNIX, stagod. Nikad nisam pominjao mikrokontrolere, i moram da


U redu, ali ako govoriš o C-u onda ne mozeš da se ograničavaš niti na tip mašine niti na operativni sistem. :)

poz.

[ Dejan Lozanovic @ 04.04.2002. 16:07 ] @
Citat:
masetrt:
Ljudi zaboravite na malloc ,realloc i free od pojave c++ se koristi new i delete

tako da bi izgledalo:

char *str;

str=new char[5];

.

.

.

delete []str;

Dinamicki nizovi su bolji i imaju nekoliko nacina pristupa, new i delete su stabilniji (pogledaj bilo koju profi statistiku) od malloc i free

da mislim elegantnije je koristiti new i delete, ali to sa druge strane ima svoju cenu, a cena je brzina. Msilim ja licno preferiram vise C++ od C-a ali kada treba da se pise nesto jako brzo, ljudi jos uvek se vracaju na C. Primer su ti UNIX kerneli.
[ Dejan Lozanovic @ 04.04.2002. 16:25 ] @
Citat:
Dragi Tata:
I ne zaboravi na



free (a[0]);



kad završiš sa tim stringom.

e ima i jedna lepa alternativa :))) ako se umesto malloc-a koristi valloc, posto malloc alocira memoriju na heap a valloc to uradi na stack :)) a lepa stvar jeste da se stack neke funkcije uvek ocisti kada f-ja udari return :))


Inace svima koji nisu dobro odradili teoriju savetujem da procitaju

http://docs.elitesecurity.org/...amming/c-c++/c/C_Ritch_Kering/

tamo ce naci sve sto treba da znaju za pocetak a savetujem da batale ove opste popularne za 21 dan. Jer koliko sam video te za 21 dan su pisane na mnogo strana a malo kazu
[ filmil @ 04.04.2002. 16:31 ] @
Citat:
SyStemOuT:
e ima i jedna lepa alternativa :))) ako se umesto malloc-a koristi valloc, posto malloc alocira memoriju na heap a valloc to uradi na stack :)) a lepa stvar jeste da se stack neke funkcije uvek ocisti kada f-ja udari return :))


Ali kerful.

To nije iz standardne C biblioteke!

Neki procesori na kojima C radi nemaju stek. Sve alloca-like funkcije nisu prenosive.

Ubr, izvinite što toliko insistiram na stdc-u, al mislim da će se isplatiti ljudima koji tek uče.

poz.

[ anatogen @ 04.04.2002. 20:11 ] @
Citat:
SyStemOuT:
e ima i jedna lepa alternativa :))) ako se umesto malloc-a koristi valloc, posto malloc alocira memoriju na heap a valloc to uradi na stack :))


Ne znam za taj valloc ali sta ima funkcija da alocira prostor na steku kada samim definisanjem
lokalnih promenljivih one dobijaju prostor na steku...


Citat:
a lepa stvar jeste da se stack neke funkcije uvek ocisti kada f-ja udari return :))


Pa zapravo ne ocisti se vec se %esp vrati tamo gde je i bio pre pozivanja funkcije pa sledeca funkcija prosto pise preko toga... zato na primer lokalne promenljive imaju slucajne vrednosti...

[ Predrag Damnjanovic @ 04.04.2002. 20:18 ] @
Citat:
filmil:
Kod programa za PC-je si u pravu. Nema potrebe da se bilo šta globalizuje.

Probaj da napises engine za 3d grafiku bez globalnih promenljiva.
Podrazumevam da engine treba da ima jednu matricu u kojoj upisuje i iz koje cita podatke o objektima na sceni.
Kako ces to da izvedes ako matrica nije globalna?
[ Ivan Dimkovic @ 04.04.2002. 22:17 ] @
Tako sto svakoj funkciji prosledis neku vrstu 'handle' (pointera) na instancu "scene" - a u toj strukturi potrpas i sve neophodne matrice, tj. sve sto identifikuje neku scenu. Nije to nista cudno, na taj nacin radi Win32 API, na primer - HWND ti je na primer pointer na neku strukturu prozora, i svaka funkcija koja radi sa prozorima zahteva da joj prosledis pointer na tvoj prozor. Nigde ne postoji neki globalni skup prozora, vec se memorijski prostor alocira kad ti pozoves CreateWindow() i sl.

Globalne promenljive treba izbegavati, jer kad budes jednom presao na multithreaded programiranje, doziveces svakojake probleme kada dve niti pokusaju da pristupe istoj globalnoj varijabli. Bukvalno sada sebi pravis dodatni posao, koji ces morati da resavas kad ti kupac bude zahtevao da biblioteka podrzava multithreaded zahteve.


Zastita, moj ti je savet da pre nego sto pocnes da se bavis sa high-level 3D grafikom dobro proucis programski jezik u kojem hoces da pises svoj paket. Iz ovoga sto sam video, ti jako slabo vladas C-om - to nije nikakva kritika, vec savet da naucis programski jezik, jer ono sto ti hoces da pises zahteva odlicno poznavanje programskih jezika i tehnika programiranja.

[ Predrag Damnjanovic @ 04.04.2002. 22:33 ] @
Vidis, to mi nije palo na pamet...
Mada, sta time dobijam?
[ Ivan Dimkovic @ 04.04.2002. 22:58 ] @
Sta dobijas?

Pa.. dobijas:

1. Mogucnost vise instanci "scene" ili kojeg vec objekta

2. Mogucnost multithreadinga - recimo ako neka aplikacija crta u vise prozora razlicite stvari, a koristi isti engine

3. Preglednost koda i lakse debagovanje

4. Veoma laku API sintaksu


Opet, kupi K&R skriptu, "Osnove Programiranja" i slicnu literaturu kako bi naucio odakle je sve to poteklo i kako se planira jedan ozbiljan projekat kao sto je ta tvoja 3D biblioteka. Baci pogled i na neke projekte u tom poslu, od njih mozes da usvojis sve sto je njihov competetive advantage - fleksibilnu arhitekturu, itd..

[ masetrt @ 05.04.2002. 00:32 ] @
Citat:
SyStemOuT:
[
da mislim elegantnije je koristiti new i delete, ali to sa druge strane ima svoju cenu, a cena je brzina. Msilim ja licno preferiram vise C++ od C-a ali kada treba da se pise nesto jako brzo, ljudi jos uvek se vracaju na C. Primer su ti UNIX kerneli.



U potpunosti se slazem sa tobom .Ovde su spominjani mikrokontroleri. Ali tu se ne koristi pravi c nego neki c script(nemojte bukvalno da shvatite, ipak se sve svodi na neki asembler) Na svakoj masini jacoj od 386 razlika je totalno neprimetna i za neke ogromne cifre (mereno gigabyte-vima
[ filmil @ 05.04.2002. 09:11 ] @
Citat:
masetrt:
mikrokontroleri. Ali tu se ne koristi pravi c nego neki c script(nemojte


Pozdrav. Sto se mikrokontrolera (i 'malih racunara') tice, rekao bih da je GCC pravi pravcati c kompajler. Al dobro, ovako odoh u off-topic.

poz.


[ leka @ 05.04.2002. 10:50 ] @
Ljudi, nemojte pogresno da me shvatite, ali OVOLIKA prepiska zbog "char *promenljiva[5]" ... shvatate sta hocu da kazem?
[ Jovan Marjanovic @ 05.04.2002. 13:06 ] @
Ma leko, vidis da smo vec uleteli u prepirku koje bolji programer od svih nas.
Isto tako moram da kazem da mi je jako drago sto pola vas nije razumelo onaj mali snippet koda koji sam napisao samo za vas.
BLUE ROCKS!