Poslao: 15 Feb 2005 11:25
|
offline
- Nom
- Građanin
- Pridružio: 17 Nov 2004
- Poruke: 168
- Gde živiš: Shanghai, China
|
Peca se zali da nema ko da ga odmeni - pa evo, probacu sa jednom kratkom lekcijom (koga zanima - ovo podrazumeva da znate sta su klase i pointeri u c++ -u).
U slucaju da je potreba da imate dinamicki alociran / dealociran niz nekih objekata u memoriji (na primer, custom-draw dugmici na ekranu, njihov broj i labele zavise od neceg) lako dodavanje / brisanje moze da se uradi na sledeci nacin:
Prvo, definicija klase:
class C_dugme
{
private:
(...)
public:
C_dugme(....paramteri....);
~C_dugme();
(...)
};
Zatim definisemo novi tip:
typedef C_dugme *pC_dugme;
Ovim imamo novi tip koji je u stvari pointer C_dugme.
Princip je da se radi sa pointerima na pointere tj. sledece:
pC_dugme *Dugme;
Dugme = new pC_dugme[broj_dugmica]; // sa ovim je definisana lista pointera na pointere
// sa ovim inicijalizujem svako dugme posebno
// konstruktoru mogu biti prosledjeni parametri kao sto su labela, velicina, pozicija, boja, ikonica i sl.
for(int i=0;i<broj_dugmica;i++)
Dugme[i] = new C_dugme(...parametri...);
// p.s. pocetno stanje moze da bude i Dugme = NULL tj. broj_dugmica = 0;
// U tom slucaju, inicijalno dodavanje novih dugmica je opisano kasnije
Kad dodajes novo dugme, uradis lako sledece (pod uslovom da je lista vec popunjena nekim dugmicima):
pC_dugme *tmp = new pC_dugme[broj_dugmica];
for(int i=0;i<broj_dugmica;i++)
tmp[i] = Dugme[i]; // sa ovim cuvamo pointere na pointere
delete[] Dugme;
Dugme = new pC_dugme[broj_dugmica+1];
for(int i=0;i<broj_dugmica;i++)
Dugme[i] = tmp[i]; // sa ovim vracamo sacuvane pointere
delete[] tmp; tmp = NULL;
// sa ovim predhodnim smo lako dodali novi pointer na pointer u listi, BEZ kopiranja memorije
// sa ovim dole inicijalizujemo dodati dugmic
Dugme[broj_dugmica] = new C_dugme(...parametri...)
broj_dugmica ++;
Isti princip vazi i za brisanje - sve bez memcpy i slicnih vratolomija.
Samo obratite paznju da SVE sto je alocirano sa new mora da ima svoj delete (odnosno sa new...[] svoj delete[] )
Znaci brisanje ide ovako:
if(!broj_dugmica) return; // nema brisanja ako ih nema vise
dugme_koje_brisemo = (.... index zeljenog dugmeta ....) ;
// ovde bi dobro dosla i sledeca provera:
if(dugme_koje_brisemo<0 || dugme_koje_brisemo>broj_dugmica-1) return; // znaci da nije validan index trazenog dugmeta - onda pali napolje
broj_dugmica--;
pC_dugme *tmp = new pC_dugme[broj_dugmica]; // privremeni pointeri, da sacuvamo one koje necemo da brisemo iz liste
int index = -1; // ovo nam sluzi za trenutni index tmp-a
for(int i=0;i<broj_dugmica+1;i++) // +1 jer je br. dugmica vec smanjen
{
if(i!=dugme_koje_brisemo) // dugme_koje_brisemo je index zeljenog dugmeta
{
index++;
tmp[index] = Dugme[i]; // sa ovim cuvamo pointere na preosalu dugmad
}
else
{
delete Dugme[i]; // brisemo alocirano dugme
Dugme[i] = NULL; // posle svakog brisanja, ovo uvek obavim
}
}
delete[] Dugme; // sad smo sacuvali preostale dugmice, ovi mogu da se brisu
Dugme = new pC_dugme[broj_dugmica]; // i napravimo nove
for(int i=0;i<broj_dugmica;i++)
Dugme[i] = tmp[i]; // prespojimo ih nazad
delete[] tmp; tmp = NULL; // i brisemo privremene pointere
I to je to!
Obratite paznju da ako je ostalo samo jedno dugme tj. broj_dugmica == 1 pre brisanja, brisnje ide:
delete Dugme[0]; Dugme[0] = NULL;
delete[] Dugme; Dugme = NULL;
broj_dugmica = 0;
Ovde i Dugme mora da bude NULL jer u slucaju da neka f-ja pokusa da ga koristi, NULL joj govori da ne postoji - time sprecavate prckanje po memoriji koja je dealocirana.
Isto tako, prilikom dodavanja prvog dugmeta, u slucaju da je Dugme == NULL tj. broj_dugmica == 0 pre dodavanja novog dugmeta, onda ide ovako:
broj_dugmica ++;
Dugme = new pC_dugme[1];
Dugme[0] = new C_dugme(...parametri....);
Ovde nema potrebe za tmp pointerima.
Citat:
Citat:
Izvinjavam se zbog dodatnog editovanja poruke - al navikao sam na TAB pri kucanju koda a ovde to ima drugi efekat
Evo, sad sam stavio onaj code
Poz. svima!
|
|
|
Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
|
|
Poslao: 15 Feb 2005 15:55
|
offline
- Peca
- Glavni Administrator
- Predrag Damnjanović
- SysAdmin i programer
- Pridružio: 17 Apr 2003
- Poruke: 23211
- Gde živiš: Niš
|
oni koji ne znaju sta su pointeri i sta su klase - nista nece shvatiti
po meni, trebalo bi krenuti od samog pocetka, i to prvo od C-a, da ljudima pokazemo kako program linearno funkcionise, sta su procedure, funkcije, promenljive.....
ali ok, trebace i ovo nekom, ko je poceo da uci C++
ako nekome nesto nije jasno od ovoga sto je Nom napisao, neka pita.
--------------
inace, tab mozes da koristis samo ako kod stavis izmedju code tag-a.
ovako:
[code]
test
[/code]
|
|
|
|
|
Poslao: 16 Feb 2005 01:47
|
offline
- Bone Collector
- Legendarni građanin
- Pridružio: 18 Apr 2003
- Poruke: 5001
- Gde živiš: Beograd
|
ja sam mislio da kad je nesto alocirano sa new [] da se to brise sa "delete [] promenljiva" da ne mora pojedinacno
i drugo zar ono dodavanje dugmeta ne bi moglo ovako
pC_dugme *tmp = new pC_dugme[broj_dugmica+1];
for(int i=0;i<broj_dugmica;i++)
tmp[i] = Dugme[i];
delete[] Dugme;
Dugme = tmp;
// sa ovim dole inicijalizujemo dodati dugmic
Dugme[broj_dugmica] = new C_dugme(...parametri...)
broj_dugmica ++;
|
|
|
|
Poslao: 16 Feb 2005 01:50
|
offline
- Nom
- Građanin
- Pridružio: 17 Nov 2004
- Poruke: 168
- Gde živiš: Shanghai, China
|
@Bone
Da bas tako - ono sto se alocira sa new[] se i brise sa delete[]
U primeru se inicijalizuju pointeri na pointere, i oni se inicijalizuju sa new[] i brisu sa delete[] dok se sam pointer inicijalizuje sa new bez [] i brise sa delete bez []
Procitaj pazljivije na koju temu je napisan primer. Problem nije alocirati / dealocirati vec DODATI ili ODUZETI iz vec alociranog niza novi objekat, bez kopiranja memorije, koristeci prednost pointera na pointere.
@Bone
Sad sam video update - da moze i tako
|
|
|
|
Poslao: 16 Feb 2005 01:54
|
offline
- Bone Collector
- Legendarni građanin
- Pridružio: 18 Apr 2003
- Poruke: 5001
- Gde živiš: Beograd
|
mislio sam zbog ovoga:
"Obratite paznju da ako je ostalo samo jedno dugme tj. broj_dugmica == 1 pre brisanja, brisnje ide:
Kod:
delete Dugme[0]; Dugme[0] = NULL;
delete[] Dugme; Dugme = NULL;
broj_dugmica = 0;
"
ne shvatam zasto ide posebno "delete Dugme[0]; Dugme[0] = NULL; "
|
|
|
|
Poslao: 16 Feb 2005 01:58
|
offline
- Nom
- Građanin
- Pridružio: 17 Nov 2004
- Poruke: 168
- Gde živiš: Shanghai, China
|
@Bone
Zato sto je Dugme[index] bilo nekad alocirano sa new C_dugme - bio je alociran pointer Dugme[0] - to je pointer a Dugme je pointer na njega.
Inace imas memory leak
Probaj - stavi u petlju da alocira sledece:
Dugme = new pC_dugme[1];
Dugme[0] = new C_dugme(...parametri...);
delete[] Dugme; Dugme = NULL;
sta bi sa drugim new???
evo probaj ovo:
for(int i=0;i<1000000000;i++)
{
typedef char *pchar;
pchar *test = new pchar[1];
test[0] = new char;
delete[] test; test = NULL;
}
u svakom pasu ces gubiti po jedan bajt memorije.
Dugme je niz od Dugme[0] Dugme[1] ....
Dugme[0] je objekat C_dugme
Sa Dugme = new pC_dugme[broj] smo inicijalizovali pointere
a objekti se inicijalizuju sa Dugme[0] = new C_dugme(...)
Dugme nije C_dugme vec pC_dugme.
|
|
|
|
Poslao: 16 Feb 2005 02:40
|
offline
- Bone Collector
- Legendarni građanin
- Pridružio: 18 Apr 2003
- Poruke: 5001
- Gde živiš: Beograd
|
eh pa tako da, ali ja nisam gore primetio kad si ti stavio pointer na pointer, i sad pokusavam da nadjem ali ne mogu da nadjem, mozda je previse kasno pa ne vidim nist ...
|
|
|
|
Poslao: 16 Feb 2005 10:56
|
offline
- Nom
- Građanin
- Pridružio: 17 Nov 2004
- Poruke: 168
- Gde živiš: Shanghai, China
|
@Bone
Sa ovim:
typedef C_dugme *pC_dugme;
sam definisao novi tip koji je pointer C_dugme.
Kasnije sam koristio ovo:
pC_dugme *Dugme;
Dugme = new pC_dugme[broj_dugmica];
Mozda je trebalo da pC_dugme nazovem drugacije, da bi bila jasnija razlika izmedju pC_dugme i C_dugme - nadam se da ce ovo razjasniti "sta je pesnik hteo da kaze"
Poz.
|
|
|
|
|