[ aleksazr @ 19.02.2013. 23:23 ] @
Recimo da koristim standardnu strukturu RECT iz windowsa i koristim pointer na RECT.

Code:

RECT *prect;

// mogu da kažem
prect->left = 0;

// ali mogu i
prect[-1].left = 0;
prect[0].left  = 0;
prect[1].left  = 0;

i kompajler se neće buniti...

Šta sam ja definisao u prvoj liniji, pointer na jedan RECT ili na array RECTa?

Kako da definišem pointer na array, ako ne znam unapred koliko RECTa ima?

Inače, pitam jer ne mogu da nateram WinDbg (a ni MSVC debugger) da mi prikaže
ceo spisak RECT struktura, a ne samo prvi.

Hvala

[Ovu poruku je menjao aleksazr dana 20.02.2013. u 10:16 GMT+1]
[ the_tosic @ 20.02.2013. 19:15 ] @
To je pointerska aritmetika.
U principu to sto si napisao i ako je potpuno pogresno ce "raditi". Doduse verovatno ces dobiti segmentation faulth.

Da skratim, odgovor na tvoje pitanje je da u watch-u umesto prect stavis prect,10 (ili tako nesto) i videces 10 struktura, pocevsi od te adrese.

**********************************************************

Posto je C/C++ jezik relativno niskog nivoa. Moguce je da uradis takve stvari bez nekog exceptiona. I nemoguce je da na osnovu pokazivaca znas duzinu niza koji si alocirao ako si ga alocirao dinamicki;

Code (c):
//Recimo u tvom kodu su pogresne sledece stvari:
RECT *prect;
prect->left = nesto;
// ovim sto si napisao ti radis sledece:
//   pravis promenjivu koja je tipa pokazivac na RECT i koja je NEINICIJALIZOVANA (random) adresa x
//   na adresu x ti upisujes neku vrednost.
//   to znaci da ako adresa x pokazuje negde u tvoj kod, ti mozes da prepises svoj program, ako pokazuje recimo na neki deo tvog os-a obaras sistem
//   ovo iznad naravno zbog koriscenja virtuelnog memorijskog prostora nije tacno, pa najgore sto mozes da uradis je da spucas svoj program

// pravilno je:
RECT *prect = (RECT*) malloc(sizeof(RECT));
prect->left = nesto;
//ili
RECT rect;
RECT *prect= ▭
prect->left = nesto;
rect.left = nesto;

// Ako hoces da kreiras niz RECT-ova
int SIZE = 5;
RECT *prect = (RECT*) malloc(sizeof(RECT) * SIZE);
// onda npr sledece grupe izraza rade istu stvar
prect->left = nesto;
prect[0].left = nesto;

(prect + 1)->left = nesto;
prect[1].left = nesto;
(prect + 2)[-1].left = nesto;

// e i dok su gornji izrazi korektni jer gadjaju alociranu memoriju
// sledeca dva izraza su nekorektna jer gadjaju nealociranu memoriju
prect[-1].left = nesto;
(prect - 2)[0].left = nesto;


 


[Ovu poruku je menjao the_tosic dana 20.02.2013. u 20:33 GMT+1]
[ aleksazr @ 20.02.2013. 19:33 ] @
Da napomenem da program koji sam dao je samo primer, dakle inicijalizuje se sve kako treba u pravom programu.

prect,10 ne radi (ispisuje integer, 0n10)
[ the_tosic @ 20.02.2013. 20:00 ] @
Zaista nemam ideju, ja sam sad probao kod sebe kreirao sam niz nekih struktura i sa ptr,5 ih vidim
Code:
-        ptr,5    0x002f9260 {{a=1 b=0x008d5858 "12ss34" }, {a=2 b=0x008d5860 "1234da" }, {a=3 b=0x008d5868 "1234ad" }, ...}    S[5]
+        [0]    {a=1 b=0x008d5858 "12ss34" }    S
+        [1]    {a=2 b=0x008d5860 "1234da" }    S
+        [2]    {a=3 b=0x008d5868 "1234ad" }    S
+        [3]    {a=4 b=0x008d5870 "1asd234" }    S
+        [4]    {a=-842150451 b=0xcdcdcdcd <Error reading characters of string.> }    S

[ Ivan Dimkovic @ 20.02.2013. 20:31 ] @
Citat:
aleksazr
Šta sam ja definisao u prvoj liniji, pointer na jedan RECT ili na array RECTa?


Deklarisao si pointer na memorijsku lokaciju velicine sizeof(RECT) i jos mu nisi dodelio vrednost, sto znaci da je memorijska lokacija nedefinisana.

C kompajler pojma nema da li se na toj lokaciji nalazi jedan RECT ili pocetak niza od dva, pet ili milion RECT-ova, ili se ne nalazi ni jedan RECT posto je pointer u nedefinisanom stanju. Moderni kompajleri ce bar primetiti da pokusavas da referenciras pointer koji nije setovan zato sto u ovom trivijalnom slucaju to mogu da zakljuce.

Medjutim, C kompajler ce ti dozvoliti da adresiras niz RECT-ova u odnosu na memorijsku lokaciju bez obzira na to da li je zaista alocirana memorija ili ne.

Tu se krije ogromna moc ali i ogromna ranjivost C koda - ako znas sta radis, mozes programirati vrlo nisko, tik malo iznad nivoa asemblera. Ali ako ne znas sta radis, ceka te gomila krahova :)