Hirdetés

2024. május 1., szerda

Gyorskeresés

Hozzászólások

(#1401) bpx válasza Vasinger! (#1400) üzenetére


bpx
őstag

mit értesz az alatt hogy újraindul?
elindítod és rögtön eltűnik az ablak? akkor indítsd debug nélkül (ctrl+f5) vagy írd be a végére hogy Console.Readkey(); és akkor még vár egy gombnyomásra mielőtt kilépne

sorok számozása: tools / options / text editor / all languages / line numbers pipa be

(#1402) Sk8erPeter válasza Sk8erPeter (#1399) üzenetére


Sk8erPeter
nagyúr

Most akkor itt megállt a tudomány? :B Mert a kérdésre még akkor mindig nem tudom a választ a dinamikus memóriafoglalással kapcsolatban.
Mármint hogy tömb-nem tömb, futásidőben történő méretnövelés, stb... Amiről korábban szó volt, hogy állítólag nem lehet tömbnek futásidőben változtatni a méretét. Most akkor mi van? :D Fogalmi képzavar?

(#1403) Karma: OK, köszi, nem sürgetésképpen írtam, csak azt hittem, hogy akkor skippeltétek a hsz.-t, mert túl hosszúra sikerült a példák miatt. :D

[ Szerkesztve ]

Sk8erPeter

(#1403) Karma válasza Sk8erPeter (#1402) üzenetére


Karma
félisten

Van aki dolgozni is jár ;] Mindjárt nézem...

Megnéztem... Mi is a kérdés?

[ Szerkesztve ]

“All nothings are not equal.”

(#1404) Vasinger! válasza bpx (#1401) üzenetére


Vasinger!
nagyúr

Köszi a segítséget, így már megy. De mi suliban is csak arra a zöld nyílra mentünk és nem indult újra. Miért is van ez? Valamit mit ha be kéne írni vagy törölni kellene. :F

Meg ha elindítom simán saját gépen, ott is egyből újraindul.

Közben kipróbáltam amit írtál, az segített. Console.Readkey();

:R :R

[ Szerkesztve ]

(#1405) Sk8erPeter válasza Karma (#1403) üzenetére


Sk8erPeter
nagyúr

A kolléga itt azt mondja, nem lehet futásidőben növelni a tömb méretét. De most akkor itt nem éppen az történik? Itt tulajdonképpen pointerrel és/vagy tömbbel játszik, de a kettő bizonyos szempontból hasonló, mégis más a kettő, és most már akkor kezdem azt sem érteni, amit azt hittem, eddig értettem :D Tehát itt a mutatott példában pl. egy új tömbnek már futásidőben foglal akkora memóriát, amekkora számára szükséges. A másikban meg még bővíti annyival, amennyi kell, mivel csak egyszer olvashatjuk be az állományt. Ugyanúgy kezeli, mint egy tömböt. De akkor most mi is az igazság?

Sk8erPeter

(#1406) Karma válasza Sk8erPeter (#1405) üzenetére


Karma
félisten

Félreértelmezted a második példát, ott sincs szó átméretezésről, egyszerűen egy tömbök tömbje szerkezetben foglalgat memóriát. Az első példára is igaz az viszont, hogy átméretezni pusztán malloc-kal nem lehet egy már lefoglalt tömböt. A realloc-kal hamarabb (realloc = malloc + memcpy + free egyben).

Az eredeti üzenet meg a fix szélességű stack/globális tömbökről szólt, nem a heapen lévőkről. Azokat tényleg nem tudod változtatni, se dinamikusan kiszabni, erre elég jó volt a kétsoros példakód.

“All nothings are not equal.”

(#1407) Vasinger!


Vasinger!
nagyúr

Mért nem müxik a tabulátor, ha így írom be?:

System.Console.WriteLine("\t\n\aszöveg");

Elvileg új sorba, bekezdéssel és pittyogással kéne kiírnia azt, hogy szöveg. Ebből a bekezdés nem működik.
Ha már itt vagyok, hogy lehet több sorral lejjebb menni nem csak egyel és középre zárni a szöveget? :F

[ Szerkesztve ]

(#1408) Karma válasza Vasinger! (#1407) üzenetére


Karma
félisten

Középre zárni úgy kell, hogy fogod a szöveged hosszát, elosztod kettővel, kivonod a képernyő szélességéből, és a kapott számszor kiírsz egy szóközt. De most ezzel asszem lelőttem a poént.

Egyébként meg egyszerű: a \t\n\a nem az, mint amit Te az előbb leírtál :)
Ez most egy tab, utána egy sortörés, végül csilingelés. Hasonlítsd össze ;)

“All nothings are not equal.”

(#1409) Vasinger! válasza Karma (#1408) üzenetére


Vasinger!
nagyúr

Az eleje teszett. :D

A-haa, így már értem, hogy a sorrend is számít, köszi!

(#1410) bpx válasza Vasinger! (#1407) üzenetére


bpx
őstag

több sorral meg úgy tudsz lejjebb menni, hogy többször írsz \n-t ("\n\n\nszoveg")

amúgy meg én 4 éve írtam az ilyen C zh-kat, most rájöttem, hogy rengeteget felejtettem
nagyon elkényelmesedtem, mindig csak java meg c# :D

[ Szerkesztve ]

(#1411) shev7 válasza Sk8erPeter (#1399) üzenetére


shev7
veterán

de pont errol beszeltem. Az ujtomb valtozo nem egy "statikus" tomb. Az egy pointer. Amirol mit is irtam? Ja tenyleg, azt hogy futasi idoben lehet neki memoriat foglalni.

Tehat megegszer, mert ugy tunik nem jon at :D

ha egy valtozot igy deklaralsz

int *tomb

az egy pointer lesz. Ponternek futasi idoben foglasz meretet, ujra foglalod stb...

ha egy valtozot igy deklaralsz:

int tomb[100]

az egy tomb, array, nevezzuk akarminek, lesz. A pointernek foglalt terulettel ellentetben ennek a memoriaigenye mar forditaskor eldol, es a stack-en fog csucsulni megvaltoztathatatlanul, es nem a heap-en ahogy a pointer altal foglalt terulet, amivel azt csinalsz amit akarsz, lefoglalod, felszabaditod, ujrafoglalod.

Ertem? :D

[ Szerkesztve ]

''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''

(#1412) Sk8erPeter válasza Karma (#1406) üzenetére


Sk8erPeter
nagyúr

Huhh. No, akkor valóban vannak homályos foltok.
Megpróbálom értelmezni akkor a lényegi kérdést, kérlek javíts, ha valamit rosszul gondolok:
A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen". Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát. Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb... :F :DDD
A második feladatban már megint ez a fogalmi zavar a bajom. (pointer, tömb, pointertömb...)
Ráadásul - bocsi az értetlenkedésért, csak vannak ilyen homályos pontok - akkor a memóriafoglalással ezek szerint nem "méretezünk", hanem nem tudom, mit csinálunk :D

És még egy pluszkérdés: a main()-ben free-vel felszabadítjuk a memóriát, de ekkor nem "szabadulunk meg" egyben az adatszerkezet már korábban eltárolt értékeitől is?

Bocs a sok kérdésért, és köszönöm az eddigi és további segítséget. :R

(#1411) shev7: pont most küldtem a hsz.-t. :D köszi, rögtön végiggondolom, hogy leülepedjen. :B És igen, jól látod, még nem jött át, kicsit zavar van most az agyamban. :D De már dereng valami! :B :R

[ Szerkesztve ]

Sk8erPeter

(#1413) shev7 válasza Sk8erPeter (#1412) üzenetére


shev7
veterán

bar nem nekem szol a kerdes probalok valaszolni, ha mar itt vagyok:

"A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen"."

Lenyegeben igen.

Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát.

Inkabb nevezzuk memoriateruletnek, de igen.

Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb...

Na itt kezdodik a fogalomzavar. Eloszor is ne hivd pointertombnek mert az nem az. A pointertom az szamomra a pointerek tombjet jelenti, es itt nem errol van szo. Hogy mi is tortenik ahhoz egy kis magyarazat.

Vegyunk eloszor egy egyszeru byte pointert: byte *p;
a p valtozo tartalma egy memoria cim. A *p ahogy a deklaraciobol is olvashato egy byteot jelent (vagyis a p pointer altal mutatott erteket). Ha tovabbmegyunk a *(p+1) - a p memoriaterulet utani byte-on levo byte-ot jelenti. Na es most jon a turpissag, maradjatok meg velem :) hogy ne legyen olyan bonyolult az elet, behoztak ezt a tomb pointer megfeleltetest. (illetve nem behoztak, eddig is igy mukodott, csak mivel korabban nem voltak pointerek, nem foglalkoztunk a problemaval) Azaz a p[5] az megegyezik azzal mintha azt irnad hogy *(p+5).

de ugye ez csak byteoknal mukodne ilyen egyszeuen. Int-nel mar bonyolultabb a tema. Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)

Namost mivel ez alapbol igy mukodott tomboknel, ( ha deklaralsz egy olyat hogy
int tomb[100]; akkor a tomb igy magaban egy pointer, es a hatterben pont egy ilyen konverzio zajlik le) akkor a pointerek bevezetesevel csak annyi tortent, hogy ez "mukodik a masik iranyba is"

MOD: ja es ezert indexeljuk 0-tol a tomboket C-ben :D

[ Szerkesztve ]

''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''

(#1414) Karma válasza Sk8erPeter (#1412) üzenetére


Karma
félisten

"A double *ujtomb; sorban tehát deklarálunk egy pointerváltozót ujtomb néven, aminek csak később foglaljuk le a szükséges memóriát, először még csak meghatározzuk, hogy "lesz ilyen"."

Igen. Bár ha nagyon szőrözni akarnék, ahogy egyszer már tettem, a megfogalmazás nem tökéletes: magát a pointert sikeresen definiáltuk, 4 byte-ot kapott a stacken (vagy globálisan), mint egy átlagos változó. De ezt most felejtsük el egy pillanatra, mert irreleváns.

"Amikor megtudtuk az eredeti tömb számunkra szükséges elemeit megszámolva, mekkora új tömbre van szükségünk, azután lefoglaltuk neki a számára szükséges memóriát. Ezután tömbként és egyben pointerként használtuk fel a későbbiekben, rakosgattunk bele elemeket, és itt ez most kicsit zavaros számomra, hogy akkor most melyik fogalmat is használjuk, ami helytálló. Mert tömbnek foglalunk helyet, de pointertömb... :F :DDD"

Nem, mi csak és kizárólag pointerként használtuk, nincs külön olyan, hogy "tömbként" használni. Ez a szép a C-ben (konkrét és ironikus értelemben is), hogy ilyen egyszerű :) Mint írtam korábban, a p[n] subscript operátor az ekvivalens a *(p+n) művelettel.

A pointertömb egy teljesen más fogalom. Pl. int **valami; egy int pointerre mutató pointer, amivel (hasonlóan a második példakódhoz) tömbök tömbjét lehet megvalósítani. Ugyanezt lehet fix méretben is: int valami[5][2];.

"Ráadásul - bocsi az értetlenkedésért, csak vannak ilyen homályos pontok - akkor a memóriafoglalással ezek szerint nem "méretezünk", hanem nem tudom, mit csinálunk :D"

A memóriafoglalással memóriát foglalunk :)

"És még egy pluszkérdés: a main()-ben free-vel felszabadítjuk a memóriát, de ekkor nem "szabadulunk meg" egyben az adatszerkezet már korábban eltárolt értékeitől is?"

Dehogynem. Amire meghívod a free-t, az felszabadul, az értékei érvénytelenné és elérhetetlenné válnak. (Legalábbis így kell bánni vele, ha nem akarsz bugzani.)

Fontos megjegyezni, hogy egy dinamikus pointertömbnél az alstruktúrákat egyesével fel kell szabadítani, a fordító nem fogja kibogozni!

“All nothings are not equal.”

(#1415) Sk8erPeter válasza shev7 (#1411) üzenetére


Sk8erPeter
nagyúr

Szóval akkor pl. az általam mutatott példában az ujtomb nevű tömb nem tömb, hanem pointer. De a tömb olyan, mint egy pointer, mert pl. függvénynek már eleve a címet adjuk át, ha tömböt adunk át. De a pointernek mások a tulajdonságai, szabadon, futásidőben változtatható a memóriaigénye, ide-oda állítgatható, stb., míg a tömbnek már fordításkor meghatározott a memóriaigénye, akármilyen adatot pakolászunk is bele (persze a megadott típus szerinti méretkorlátokon belül). Tehát a tömbnek ha megszakadunk, sem tudunk változtatni futásidőben a memóriaszükségletén.
Az eddigiek helytállóak? És "csupán" ilyen szempontból van eltérés?

Szerk.: jól "egyszerre" írtuk a hsz.-eket, olvasom is a válaszaitokat. :R

[ Szerkesztve ]

Sk8erPeter

(#1416) Karma válasza shev7 (#1413) üzenetére


Karma
félisten

"de ugye ez csak byteoknal mukodne ilyen egyszeuen. Int-nel mar bonyolultabb a tema. Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)"

Nem igaz!

Ha a p ebben a példában egy int*, akkor automatikusan egy egész értéknyit lép előre, nem kell és nem szabad a sizeoffal varázsolni benne! Tehát 32 biten "p+1" az 32 bittel előrébb mutat, nem csak egy bájttal!

[ Szerkesztve ]

“All nothings are not equal.”

(#1417) shev7 válasza Karma (#1416) üzenetére


shev7
veterán

hopsz, akkor ezt rosszul tudtam, regen volt mar. Mi a helyzet a p egy double*?

''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''

(#1418) Karma válasza shev7 (#1417) üzenetére


Karma
félisten

Jo kerdes, meg csak egeszeket hasznaltam (8, 16, 32 bit szelessegben), de nem latom okat annak, hogy mashogy mukodjö (sizeof(double) is fix ertek).

“All nothings are not equal.”

(#1419) Karma válasza Karma (#1418) üzenetére


Karma
félisten

Utánanéztem (google://double pointer arithmetic), a fordítók double-nél, structoknál, de még statikusan deklarált tömböknél is van elég okos ahhoz, hogy helyesen lépjen előre :)

“All nothings are not equal.”

(#1420) Sk8erPeter válasza Karma (#1414) üzenetére


Sk8erPeter
nagyúr

Köszi a válaszokat, Karma és shev7, azt hiszem, már nagyjából értem. :R

"magát a pointert sikeresen definiáltuk, 4 byte-ot kapott a stacken (vagy globálisan), mint egy átlagos változó. De ezt most felejtsük el egy pillanatra, mert irreleváns." És hogy is van tovább? :)

"Dehogynem. Amire meghívod a free-t, az felszabadul, az értékei érvénytelenné és elérhetetlenné válnak."
Mondjuk jelen esetben a példaprogramnál ez nem volt világos, hogy minek foglaltunk akkor helyet az adatoknak, ha utána rögtön az eltárolás után meg is szabadultunk tőle. Igaz, erre lehetne azt mondani, hogy mivel nem volt része a feladatnak az, hogy tovább tárolgassuk, és még csináljunk vele valamit, csak a szavakra darabolás.

(#1413) shev7: "Ott a kovetkezo egyenloseg igaz: p[5] = *(p+sizeof(int)*5)" Ettől egy kicsit megijedtem, mivel pont nem ezt tanultuk, hanem azt, hogy azzal egyenlő, hogy *(p+5). :) De látom később megbeszéltétek, hogy valóban az utóbbi a jó.
Itt viszont nem értettem az összefüggést: "ja es ezert indexeljuk 0-tol a tomboket C-ben" azzal, amit ezelőtt írtál.
Egyébként számomra az is újdonság volt, hogy lehet deklarálni úgy egy változót, hogy byte *p; . Ez mire jó ebben a formában? Még konkrét programban kevésszer láttam így deklarálva egy változót, de valamilyen szempontból nyilván hasznos lehet.

Köszi nektek a türelmes válaszokat! :R

Sk8erPeter

(#1421) shev7 válasza Sk8erPeter (#1420) üzenetére


shev7
veterán

mert ha egytol indexelnenk, akkor
p[1] = *p
p[2]= *(p+1)
.
.
.

0-s indexelesnel mindket oldalon ugyan az a szam van :D

"hogy lehet deklarálni úgy egy változót, hogy byte *p; . Ez mire jó ebben a formában? "

Na most ennek utananeztem, hogy ne irjak hulyeseget. A lenyege, hogy egyertelmu legyen. A * operator ugyanis jobbra kot. Barmennyire is irod kozel a tipushoz :)

Szoval ha irsz egy ilyet:

long* first, second;

akkor deklaraltal egy long pointert (first) es egy long valtozot (second). De akkor mar miert nem irnad le egyertelmuen:

long *first, second; es igy senki nem fogja azt gondolni hogy ket pointert deklaraltal.

''Gee, Brain, what do you want to do tonight?'' ''The same thing we do every night, Pinky: Try to take over the world!''

(#1422) Karma válasza Sk8erPeter (#1420) üzenetére


Karma
félisten

"És hogy is van tovább? :)"

Igazából nincs itt sok már, csak azért tereltem el a szót, hogy ne legyen kavar. :N
A pointer a háttérben mindig egy 32/64 bites int szám, egyszerű változó, és úgy is viselkedik, mintha egy sima int változód lenne.

"Mondjuk jelen esetben a példaprogramnál ez nem volt világos, hogy minek foglaltunk akkor helyet az adatoknak, ha utána rögtön az eltárolás után meg is szabadultunk tőle. Igaz, erre lehetne azt mondani, hogy mivel nem volt része a feladatnak az, hogy tovább tárolgassuk, és még csináljunk vele valamit, csak a szavakra darabolás."

Pontosan ez történt :) Felépíti, és el is tünteti. Szerintem durva pontlevonás járna érte, ha nem tenné a hallgató. Viszont cserébe jól bemutatja, hogy egy fésűs adatszerkezetet hogy kell felszabadítani.

“All nothings are not equal.”

(#1423) Karma válasza shev7 (#1421) üzenetére


Karma
félisten

Pfff, az előbb a fórummotor kidobta a szerkesztésemet a kukába...

Szóval az általad említett problémának van egy alternatív megoldása, ha az adott környezet úgy kívánja meg (szerencsére a legtöbbet ilyenben dolgozok, én a típushoz szeretem kötni a *-ot és a &-et :) ):

int* first;
int* second;

“All nothings are not equal.”

(#1424) Sk8erPeter válasza shev7 (#1421) üzenetére


Sk8erPeter
nagyúr

Nem a * operátor sorrendjén voltam meglepődve, hanem magán a "byte" típuson. :B Eddig nem használtam, és nem is igazán láttam gyakorlati feladatokban konkrétan ezt a típust. Szóval erre kérdeztem, hogy mire jó. :D
Egyébként jó, hogy felhívtad a figyelmem, hogy attól még, hogy a csillagot a típus mögé rakom közvetlenül, nem lesz a következő változó is automatikusan pointer :D (mondjuk ez viszonylag egyértelműnek látszik, de nehogy elcsesszem valamikor - most már nem fogom)
Köszi a választ ismét! :R

(#1422) Karma: neked is köszi! Ez mitől lesz egyébként "fésűs adatszerkezet"?

[ Szerkesztve ]

Sk8erPeter

(#1425) m0h0senator


m0h0senator
őstag

Sziasztok,

adott egy feladat: bekérünk egy számot a felhasználótól, a szám tulajdonságai: számjegyei 0-7 ig lehetnek és max 5 jegyű lehet. ezt a számot egy karakter tömbben tároljuk el. Az lenne a kérdésem,hogy hogy döntöm el a számról, hogy hány jegyű? És a karakter tömbnek milyen szintaktikái vannak?

előre is köszönöm :R :R

An odyssey through the realm of consciousness.

(#1426) bpx válasza m0h0senator (#1425) üzenetére


bpx
őstag

egy számról sokféleképpen meg lehet állapítani hogy hány jegyű, de a feladat szövege sugallja (karaktertömb), hogy érdemes karakterenként bekérni a számot
ekkor legfeljebb 5 karaktert kell egyenként bekérni, amit rögtön lehet ellenőrizni is, hogy beleesik-e a 0..7 tartományba

szintaktika: a legegyszerűbbet amit csak lehet (dinamikus memóriafoglalás itt felesleges)

char tomb[5];
char c;

....

c = getch();

....

tomb[0] = c;

(#1427) Karma válasza Sk8erPeter (#1424) üzenetére


Karma
félisten

Ezért fésűs (a nyilak a pointereket jelölik):

Egy kicsit elrontottam a képet, minden szó végén ott van még egy 0 is, lezárva a szavakat. A függőleges oszlopban meg csak akkor vannak 0-k, ha calloc-kal lett lefoglalva, vagy kézzel ki lett előre nullázva. De sajnos Excelben rajzoltam, és becsuktam a doksit :(

[ Szerkesztve ]

“All nothings are not equal.”

(#1428) 3man


3man
csendes tag

Ha mar igy kiveseztetek a tomboket, erdemes megemliteni, hogy a legeldugodtabb bugokat a tombok tulindexelesevel lehet krealni.

Ugyanis az tortenik, hogy ha letrehozok egy int tomb[100] meretu tombot, es utanna beleirok mondjuk a tomb[234]=1 elemebe ezzel a sorral, akkor az a memoriaban utanna levo valamelyik valtozoba fog belebarmolni. Ez azutan vagy lathato hibat okoz, vagy lopakodo uzemmodban egyszercsak ertelmetlen dolgokat fog a program csinalni teljesen mashol, olyan helyen, aminek semmi koze a tomb[] hoz.

Erre mar jol kezelheto array osztalyok vannak, erdemes szetnezni es valogatni ezek kozt. A legegyszerubb, ha az ember egy sajat array osztalyt hoz letre, es minden tipusu tombot ezzel definial.
Ebben letre lehet hozni egy []-operatort, ahol az indexelesnel ellenorizni lehet, hogy az index a tomb merete alatt van-e. A tomb letrehozasanal pedig el lehet tarolni a meretet. Ezzel az apro dologgal rengeteg fejfajastol lehet megszabadulni.

Ehhez kapcsolodik a memoria kezeles. Ha az ember meg kezdo, nem mindig tudja ugy felepiteni a programot, hogy minden lefoglalt memoria mindig jo helyen es jo idoben szabaduljon fel.
Minden new utasitast erdemes sajatra cserelni. Ez akar egy egyszeru makroval is megteheto. Egy mutato-listat letrehozva le kell tarolni minden lefoglalt cimet.
Amikor uj cimet hozok letre, erdemes vegignezni a listat, hogy nem esik bele valamelyik mar letrehozott memoria reszbe az uj kezdocim. Igy kiszurheto olyan rejtett memoria hiba, ami akkor keletkezik ha lemasolok egy pointert, de az eredetit felszabaditom. Ez kezdo hiba, de barki tevedhet. A program viszont eszre fogja venni a tevedest. Termeszetesen a delete-nel a a listabol torolni kell a mutatot.
Ezt a modszert kiegeszitve azzal, hogy minden sajat new hivasnak nevet adok, a nem felszabaditott memoriat barmikor ki lehet listazni.
Nevadas helyett lehet hasznalni a __line__ __file__ __function__ makrokat, amikkel a felszabaditatlanul maradt new utasitas pontos helyet vissza lehet kovetni.

Ezzel az ket egyszeru modszerrel szinte az osszes memoria bug kiirthato egy akarmilyen bonyolult programbol.

(#1429) Karma válasza 3man (#1428) üzenetére


Karma
félisten

:R, bár én részemről elsősorban a sima C-ről beszéltem, ott azért annyira nincs elengedve az ember array osztályokkal vagy new operátorral :)

“All nothings are not equal.”

(#1430) 3man


3man
csendes tag

"Igy kiszurheto olyan rejtett memoria hiba, ami akkor keletkezik ha lemasolok egy pointert, de az eredetit felszabaditom. "

Az kifelejtettem, hogy ennek a kiszuresehez minden [] operatornal ellenorizni kell, hogy az adott pointer benne van-e meg a listaban. Ez nagyon lelassitja a programot, de ezt eleg csak akkor futtatni, ha valamilyen bug van a programban.

Egy rutinos programozo mondhatna erre, hogy ilyen hibak nala nem fordulhatnak elo. En erre csak azt mondom, sose lehet tudni.

(#1431) 3man válasza Karma (#1429) üzenetére


3man
csendes tag

Tudom hogy ez egy c-topik, de mivel itt kerult szoba a tomb, ezert ide irtam.

(#1432) Karma válasza 3man (#1431) üzenetére


Karma
félisten

Nem azért mondom (nem is tudom, van külön C++ topik is?), mindössze az, hogy ez tényleg sokkal körülményesebb C-ben. Egyébként én meg (Symbian) a HookLoggert szoktam használni, ha memory leakre vadászom: a saját kódom módosítása nélkül végzi el ugyanezt, amit Te az előbb manuális módszerként leírtál. (Rendszerszinten áll rá az Alloc/Free-re).

Linuxon és tsa. másik alternatíva lehet még a Valgrind is.

“All nothings are not equal.”

(#1433) Sk8erPeter válasza Karma (#1427) üzenetére


Sk8erPeter
nagyúr

Értem, köszi! :R

(#1428) 3man: még C++-hoz nem konyítok, de csak érdeklődésképp kérdezem, hogy miért nem egyszerűbb a túlindexelés elkerülésére osztály létrehozása helyett mindig "kényszerűen" átadni a tömbméretet is mondjuk függvénynek, vagy végigszaladni a tömbelemeken a lezáró nulláig, hogy megtudjuk, hány eleme van, és utána ezzel dolgozzunk?

Sk8erPeter

(#1434) Karma válasza Sk8erPeter (#1433) üzenetére


Karma
félisten

Nem nekem szól a kérdés, de azért van pár ötletem:
1) Méretet átadni stack/statikus tömböknél redundáns információ (sizeof() megmondja).
2) Egyébként is, ezt a "belső" információt kívülről átadni csak még egy hibaforrás.
3) A \0 karaktertömböknél elmegy (bár nem 100%-os biztonság), pointertömböknél már körülményesebb (mi van, ha nincs tele a tömb? Mivel töltöd fel?), egyéb tömböknél meg teljesen megvalósíthatatlan önmagában.

Az igazi megoldás tényleg a tömbosztályok használata, de osztályok (szintaktikailag) csak a C++-ban vannak. Szemantikailag viszont megoldható C-ben is egy kis gondolkodással: struktúrával és az azt manipuláló függvényekkel - bár szerintem nem találom fel a spanyolviaszt, biztosan más már írt ilyet.

“All nothings are not equal.”

(#1435) Sk8erPeter válasza Karma (#1434) üzenetére


Sk8erPeter
nagyúr

Abból indultam ki, hogy nekünk azt erőltették, hogy ha akár statikus tömbökkel is dolgozunk (persze, nem a pointertömbökre gondoltam :B), és azokat adjuk át a függvényeknek, akkor lehetőleg adjuk át a méretét is, mert így könnyebb kezelni (pl. ha iterátorral rohangászol végig a tömbelemeken, akkor mittomén, for ciklusban a feltétel lehet az, hogy i<meret, stb. - persze úgy is lehetne, hogy tomb[i] != '\0' ), nem kell a függvényen belül is sizeof()-fal p×csölni, és így esetleg pl. main()-ben mondjuk elég egyszer sizeof-olni (talán ez gyorsaság szempontjából is érdekes lehet, fene tudja). Ez nem lehet elfogadható szempont? A 2-3. pont mondjuk teljesen igaz.

[ Szerkesztve ]

Sk8erPeter

(#1436) Jester01 válasza 3man (#1430) üzenetére


Jester01
veterán

MOD: ja látom Karma már említette, akkor storno :B

[ Szerkesztve ]

Jester

(#1437) Badb0y


Badb0y
addikt

Valaki hozzáértő ezt össze tudja dobni :) ?

Készítsen olyan FARM-ot leíró osztályt, melyben három fajta állatot tartanak nyilván.
A FARM-on végezhető műveletek:

- AddMarha (név, kor, tejhozam) új marha felvétele
- AddLo (név, fogszám) új ló felvétele
- AddTyuk (név, tojáspernap) új tyúk felvétele
- Kill(név) Egy, a megadott nevű állat lemészárlása
- List () a még élő állatok attribútumainak listázása

Életmentő lenne :)

[ Szerkesztve ]

Minőségi laptopok https://notebookokhu.business.site/

(#1438) doc válasza Badb0y (#1437) üzenetére


doc
nagyúr

ezt milyen megfontolasbol irtad a 'C' topicba? az osztaly ismeretlen fogalom a C-ben
ezzel inkabb a programozas totyikba menj, meg nem art leirni hogy milyen nyelvrol van szo, plusz az altalad eddig megalkotott kodot berakni, azt ne vard hogy valaki csak ugy megirja helyetted a hazidat

(#1439) Badb0y válasza doc (#1438) üzenetére


Badb0y
addikt

C topikba jöttem, mert van egy olyan sanda gyanúm, hogy akik itt vannak valószínű értenek C++-hoz is.

Természetesen megegyezés kérdése, nem ingyen várom.

Minőségi laptopok https://notebookokhu.business.site/

(#1440) Jester01 válasza Badb0y (#1437) üzenetére


Jester01
veterán

Az is nagy marha aki képes volt ilyen feladatkiírásra "AddMarha" ... utálom a vegyes magyar-angol neveket. :U

MOD: Badb0y, milyen laptopot adsz érte cserébe? :DDD

[ Szerkesztve ]

Jester

(#1441) Badb0y válasza Jester01 (#1440) üzenetére


Badb0y
addikt

:DD

Minőségi laptopok https://notebookokhu.business.site/

(#1442) 3man válasza Sk8erPeter (#1435) üzenetére


3man
csendes tag

Ha az osztaly tartalmazza a tomb meretet, akkor egy gonddal kevesebb, nem kell ra figyelni.
De ez ugyan az, mint amikor atadod kezzel.

(#1443) 3man válasza Sk8erPeter (#1435) üzenetére


3man
csendes tag

Minel kevesebb dologra kell figyelni kodolaskor, annal kisebb az eselye a tevedesnek.

(#1444) Karma válasza Sk8erPeter (#1435) üzenetére


Karma
félisten

Hát nem tudom, oktatnak érdekes dolgokat :U Mondjuk production kódot még nem írtam/láttam sima C-ben, lehet hogy tényleg van ilyen konvenció.

De nem esküdnék meg rá. Nemrég láttam, hogy valahol a BME-n is goto-val tanítják a Pascalt! :Y Akkora lett a fejem hogy csak na...

Egyébként az, hogy végigiterálsz a tömbön, még nem jelenti azt, hogy iterátorral dolgoznál. Az iterátor egy objektum-orientált minta. Röviden: ahelyett, hogy ismerned kéne a tömb/lista/stream/kismacska belső szerkezetét, és ezt figyelembe véve temérdek kódot generálnál, kérsz a kollekciótól egy iterátort, egy általános interfészt megvalósító objektumot, aminek ilyen műveletei vannak tipikusan: hasNext(), next(), removeCurrent(), satöbbi. Így szerkezettől független kódot tudsz írni :)

A szempontod egyébként jogos, de most hogy leírtam az előző blokkot leesett, hogy igazából miért is jobb kézzel átadni a hosszt kívülről: ezzel egységesen lehet kezelni a fix méretű és a heapen lévő tömböket is!

“All nothings are not equal.”

(#1445) 3man válasza Karma (#1432) üzenetére


3man
csendes tag

Termeszetesen debuggerekkel es tarsaikkal helyettesitheto a modszerem.
De amikor 10 netalan 100 kulso tesztelod van, akkor nem biztos, hogy ez kenyelmes modszer.
Mi a legegyszerubb megoldas?
Az AddVectoredExceptionHandler() -el elkapsz minden nem tervezett esemenyt, es logolsz minden fontos dolgot. A lefoglalt teruletek mutatolistaihoz rendelt nev alapjan barmilyen memoria hiba pontosan lokalizalhato akar ugy, hogy nem is debug modban fut a program. Egy callstack-hez hasonlo kovetes is beepitheto ebbe a logba.
Ugyan a debug mod azert van, hogy ezt elvegezze, de megeshet, hogy igy tul lassu a program. Ha a programot a vegleges formajaban kell tesztelni, akkor a debug mod mar kiesik, de a hiba megis egyszeruen detektalhato.

[ Szerkesztve ]

(#1446) bama


bama
csendes tag

Hi 3man!!!

Segitesz a progiba???

void isPrim(int number){
if (number <<4){
return number;
for(int i=4, i*i<number,i++);
if(number % i=0)
return 0;
return 1;
}

Thanx

(#1447) Sk8erPeter válasza Karma (#1444) üzenetére


Sk8erPeter
nagyúr

Nem, BME-n kifejezetten és erősen tiltják a goto utasítás használatát! Ezt a tanárok "halálfejes hibának" nevezik, ha ilyet teszel a ZH-dba, akkor rárajzolnak egy halálfejet (egyébként tényleg rárajzolják, ZH-megtekintésnél pár papíron láttam is :DDD), és arra a feladatra - akármilyen szép is a többi része - eleve 0 pontot adnak. (olyan esetekben is kapsz ilyet, ha nem szabadítod fel a dinamikusan lefoglalt memóriát, amikor kellene, vagy inicializálatlan változóval dolgozol, stb.)
Elképzelhető, hogy régebben volt olyan tanár, akinek nem verték a fejébe, hogy goto-t nem használunk, de szerintem most már selejtezik az ilyeneket. :D
Pascalt nem is tudom, tanítanak-e még egyáltalán... Villamosmérnöki és Informatikai Karon biztos, hogy nem, ott C-vel kezdenek. De én úgy tudom, hogy még az építészek is alap C-t tanulnak. Pascalról mostanában egyáltalán nem hallottam, hogy valahol tanítanának még BME-n.

A lényegre térve nem igazán értem, miért olyan nagyon hibás az elképzelés, hogy kívülről adjuk meg a függvénynek a méretet. :F Jahh, de az utolsó bekezdésben azt írod, hogy végül is van elfogadható érvelés erre is: akkor tehát mégis jó úgy? :B
Az "iterátor" szót lehet, hogy rosszul használtam, de arra az elemre gondoltam, amivel bejárod a tömböt.

A goto utasításra visszatérve: tudom, hogy a használata egy undormány-hányadék hiba, és soha nem is tettem, mert direkt meg se néztem, hogy kell azt egyáltalán :D De érdekelne, konkrétan milyen szempontból oltári baromság a goto használata. Úgy emlékszem, hogy futásidejű összeomlásokat eredményezhet, meg hasonlókat, de a pontos érveket már elfelejtettem.

(#1442) 3man: értem, köszi. Tehát akkor érdemes mégis kézzel átadni (ha sima C-ben programozol) a tömbméretet, ugye?

(#1446) bama: most mi a kérdés? Egyébként ha ez egy prímtesztelő függvény, akkor szvsz elég furcsa, minek kell 4-gyel shiftelni a számot...

[ Szerkesztve ]

Sk8erPeter

(#1448) kovsol válasza Sk8erPeter (#1447) üzenetére


kovsol
titán

goto val ugyan az a helyzet itt nálunk is
persze mikor assembly óra van ott ugrások nélkül kivitelezhetetlen a dolog :) de ugye ez itt a C topic

May the Force be with you!

(#1449) dabadab válasza Sk8erPeter (#1447) üzenetére


dabadab
titán

A goto azert nem jo, mert tonkrevagja a program strukturajat, ami nehezebbe teszi a hibakeresest, a kod karbantarsat es megerteset is.
Azt mondjuk nem art nem elfelejteni, hogy Dijsktra '68-ban irta "Go To Statement Considered Harmful" cimmel megjelent levelet, amikor a strukturalt programozas meg nem volt igazan mainstream es teljesen hetkoznapi volt a spagettikod, amiben gotoval ugraltak ossze-vissza. Bizonyos helyzetekben azon a goto hasznos lehet, mert eppen pont az adja a leghatekonyabb vagy a legattekinthetobb kodot - annak idejen a Kandon is belefutottam abba, hogy gyakorlaton instantegyes volt a goto, eloadason meg a quicksortbol egy gotos verziot prezentalt a tanar, mert az volt a legegyszerubb.
Mindent osszefoglalva, a goto elleni liheges mara nagyreszt okafogyotta valt (ma mar senki nem hasznalja ugy, ahogy a hatvanas evekben), az ellene valo horges mogott pedig ritkan talalni ertelmes okokat.

DRM is theft

(#1450) Karma válasza Sk8erPeter (#1447) üzenetére


Karma
félisten

Tudom hogy VIK-en mi a helyzet, én is informatikus-hallgató vagyok (félig) :P Viszont egy másik fórumozónak segítettem Pascalban, és ő másolt be órai kódot, ami hemzsegett tőle. Nem mondta el, melyik szak, én részemről GTK-ra tippelnék, vagy TTK-ra.

Nem hibás elképzelés! Sőt, mint írtam az üzenetem végén, ha egységesen akarod kezelni a stacken, globálisan és a heapen lévő tömböket, akkor nincs is nagyon más lehetőséged rá. Hacsak nem varázsolsz struktúrákkal, és írsz OO kódot nyers C-ben. Good stuff. Szóval teljesen jó.

Egyszerűen, ahogy 3man is mondta, amit nem Neked kell karbantartanod, az nem lesz hibalehetőség később. A KISS ("Keep It Simple, Stupid!") filozófia általában jó eredményeket hoz.

Értettem mire gondolsz az iterátor szóval :R, csak belejavítottam.

Apropó goto. Igazából a dolog kettős. Van olyan helyzet (főleg C-ben, meg ahogy kovsol is írja, assemblyben végképp), amikor előnyös a használata. Például hibakezelésre kivételek helyett, vagy brutálisan mély feltételeket szétbontani (Linux kernelben láttam most rá egy példát, amikor az előbb rákerestem). Viszont nem arra való, hogy a program teljes logikáját ezzel írja meg az ember, mint amit az említett órán csináltak ("ha a user 1-et ír be, kezdjük elölről a programot" jellegű varázs). Itt van róla egy hosszú, de annál érdekesebb leírás.

“All nothings are not equal.”

Copyright © 2000-2024 PROHARDVER Informatikai Kft.