Gå til innhold

Array størrelse via pointer


Anbefalte innlegg

Hei

 

kjapt og brutalt:

 

int block[10];
for (i=0;i<10;i++) { block[i] = i; }
cout << "Størrelse er: " << (sizeof(block)/sizeof(int)) << endl;

 

dette er greit.. men hvis jeg har en array av pointers:

 

int* block = new int[10];
for (i=0;i<10;i++) { block[i] = i; }
cout << "Størrelse er: " << (sizeof(block)/sizeof(int)) << endl;

så gir dette verdien 0 .. dette sjønner jeg, fordi jeg får størrelsen av pointern..

 

men jeg vil ha størrelsen av, eller antall pointers av typen 'block', for å kunne bruke sizeof funksjonen til å bestemme antall iterasjoner..

Lenke til kommentar
Videoannonse
Annonse

Må innrømme jeg ikke helt skjønner spørsmålet, men du har ikke en array av pointers i den andre kodesnutten din. Du har en peker til et array med integers. Det er ingen måte du kan finne ut av størrelsen på dette arrayet (ivertfall som jeg vet om) utenom å selv lagre lengden et sted. Om du egentlig ville ha et array av pointers så måtte du deklarert det som int* block[] eller noe lignende, og da vil sizeof() fungere som vanlig.

Lenke til kommentar

Det finnes funksjoner for å finne størrelser på minneblokke (HeapSize i Windows) men det beste er nok å bare lagre det et sted så det er enkelt tilgjengelig, som de aller fleste containerklasser gjør for deg. En grunn er at funksjonene for dette er operativsystemavhengig, og en annen er at det er ingen garanti for hvor raske de er.

Merk at int my_block[20] allokerer 20 32bit integer på stack, mens int my_block[] = new int[20] allokerer 20 integer på heap. sizeof gir deg kun størrelsen på data som er lagret på stack, og vil derfor returnere 20*sizeof(int) for første, og 1*sizeof(int*) på neste.

Lenke til kommentar

Merk at int my_block[20] allokerer 20 32bit integer på stack,

 

Hvor i språkdefinisjonen er det garantert at:

 

* 1 int er 32 bits stor

* Definisjonen over vil faktisk allokere plass på stacken (eller at stacken overhodet eksisterer)

 

sizeof gir deg kun størrelsen på data som er lagret på stack, (...)

 

Hvor i alle dager tar du dette fra? Operanden til sizeof trenger ikke å være lagret noen steder i det hele tatt! Når jeg tenker meg om er dette et krav, da sizeof()-operatoren returnerer en konstant.

Endret av zotbar1234
Lenke til kommentar

Hvor i alle dager tar du dette fra? Operanden til sizeof trenger ikke å være lagret noen steder i det hele tatt! Når jeg tenker meg om er dette et krav, da sizeof()-operatoren returnerer en konstant.

...og konsekvensen vil derfor være akkurat det jeg skrev.

 

Hvorfor gidder du å kommentere hvis du ikke har noe viktig å komme med?

Endret av GeirGrusom
Lenke til kommentar

Hvor i alle dager tar du dette fra? Operanden til sizeof trenger ikke å være lagret noen steder i det hele tatt! Når jeg tenker meg om er dette et krav, da sizeof()-operatoren returnerer en konstant.

...og konsekvensen vil derfor være akkurat det jeg skrev.

 

Nei. Tenk litt over hvorfor.

 

Hvorfor gidder du å kommentere hvis du ikke har noe viktig å komme med?

 

Du kommer med en feilaktig påstand og deretter presterer å lire av deg dette?

Lenke til kommentar

Han snakker vel om x86 på en 32-bit maskin da, noe som er en god nok antakelse for de fleste.

 

Hvor er int-størrelsen garantert til å være 32-bit? (og x86 er en god nok antagelse for "de fleste" i 2010? Hahaha)

 

Så teit å leke dum ass (...)

 

Kanskje lære å stave først? Hvis du skal hekte "dumbass"-merkelappene på andre, altså.

Lenke til kommentar

Du er en vemmelig person. Størrelsen på int har utelukkende med kompilatoren å gjøre. I Visual C++ er int 32-bit enten du kompilerer med 32 eller 64-bit.

http://msdn.microsoft.com/en-us/library/s3f49ktz(VS.80).aspx

Det kan være annerledes i andre compilere, og jeg er fullstendig klar over det. Men dette er en hjelpetråd, ikke være-et-rasshøl-tråd.

 

Dersom du tar sizeof(envariabel) vil det være det samme som størrelsen variabelen krever av stackområde.

Så hvis det er sizeof(char minvar[20]) = sizeof(minvar) = sizeof(char[20]) = 20

sizeof(int* ptr) = sizeof(ptr) = sizeof(int*) = 8/16/24/32/64 avhengig av kompilatoren som er brukt.

 

Tidligere C compilere ville tilogmed oversatt variabeldeklerasjoner med noe slikt:

add esp, sizeof(variabel)

 

Du må nesten påpeke hvordan jeg tar feil, fordi jeg kan ikke se det.

Endret av GeirGrusom
Lenke til kommentar

Det kan være annerledes i andre compilere, og jeg er fullstendig klar over det. Men dette er en hjelpetråd, ikke være-et-rasshøl-tråd.

 

Så hva om du begynner å hjelpe ved å gi riktige svar? Ville ikke det ha vært noe?

 

Dersom du tar sizeof(envariabel) vil det være det samme som størrelsen variabelen krever av stackområde.

 

Denne setningen gir ikke mening. For det første er ikke "stackområde" en del av definisjonen til C++. For det andre er ikke størrelsen til en variabel definert.

 

Så, hva om du holder til det som faktisk *er* definert? sizeof returnerer størrelsen til objektrepresentasjonen (object representation) til operanden. Det uavhengig av hvorvidt implementasjonen overhodet bruker en stack. Det å overhodet nevne allokeringsmodellen i dette tilfellet var hverken nødvendig eller hjelpsomt.

 

Så hvis det er sizeof(char minvar[20]) = sizeof(minvar) = sizeof(char[20]) = 20

sizeof(int* ptr) = sizeof(ptr) = sizeof(int*) = 8/16/24/32/64 avhengig av kompilatoren som er brukt.

 

Kan du slutte å servere ting som er direkte feil? Operanden til sizeof er enten en expression eller en type-id. "char minvar[20]" er ingen av delene.

 

Du må nesten påpeke hvordan jeg tar feil, fordi jeg kan ikke se det.

 

Ja, jeg forstår det.

 

  1. "Merk at int my_block[20] allokerer 20 32bit integer på stack" er direkte feil. Denne definisjonen trenger ikke å allokere noe plass på stacken (definisjonen kan ha static storage duration og bli stappet i eget passende segment, for de arkitekturene der dette er tillatt/rimelig. Eller kan det være en implementasjon som er fullstendig heap-basert, der stack overhodet ikke er i bruk). Denne definisjonen trenger ikke å allokere 20*32-bits, da sizeof(int)*CHAR_BITS ikke er garantert til å være 32. 2 feil bare der.
  2. "... mens int my_block[] = new int[20] allokerer 20 integer på heap." -- den eneste "heap" som standarden nevner er en datastruktur der sletting av minste/største-element foregår i O(log(n)) (selv om jeg personlig har vansker med å se hvordan all semantikken til new/new[] skal kunne implementeres ved å bruke noe annet enn (minne) heap på en typisk arkitektur i dag).
  3. "sizeof gir deg kun størrelsen på data som er lagret på stack" er hinsides nissevås, slik forklart alt.

 

Du kunne ha valgt å fokusere på at sizeof returnerer størrelsen av typen til operanden (være det en type-id eller ett uttrykk), beregnes compile-time og kan derfor brukes til å skrive slik kode:

 

T *p = malloc(20 * sizeof *p);

 

(et vesentlig aspekt i denne snutten er nettopp at operanden til sizeof ikke er allokert).

 

Men neida. Du valgte å gnåle videre om 32/64-bits, enda du ikke hadde noe å støtte deg på i språkdefinisjonen.

 

Ser du feilene dine nå?

Lenke til kommentar

Du er klar over at du kan bable og bable om teori og om hva standarden definerer i hytt og gevær, men om du skulle definert en egen standard for zotbar--, ditt framtidige språk, så ville du ikke kommet noe sted som helst, fordi i praksis har det vært maskinvare og hva som faktisk funker som har styrt opphavet til standardene, ikke motsatt.

 

Når det er sagt, vil jeg også legge til at jeg er rimelig sikker på at trådstarter fikk uendelig mer utbytte av det innlegget GeirGrusom skrev i starten, i motsetning til hva du prøver å bidra med i denne tråden. Har du vurdert å bli exphilforeleser?

 

Men jeg skjønner godt at du vil kverulere, det er jo faktisk lidderlig god underholdning å se hva du presterer å skrive!

Lenke til kommentar

Selvsagt var det noe analt du kom med.

 

Ah, takk for at du demonstrerer utstrekningen til din "hjelp". Du har altså ingenting å si på de faktiske innvendingene eller korrektheten deres, men du lirer av deg denne dritten i en teknisk diskusjon. Herr "hjelpsom".

Du lirer av deg denne dritten i en hjelpetråd.

Det er ingen som sitter og skriver kode for teoretiske kompilatorer. Det er heller ingen som sitter og programmerer teoretiske prosessorer. Visual C++ og GNU C++ bruker begge stack for å allokere variabler. Det er derfor NYTTIG for alle nybegynnere å være klar over dette, og hvordan det fungerer. Både med tanke på sikkerhetshull, og potensielle problemer en kan få med stack overflow, og hvorfor bieffektene er som de er.

At det på 50-tallet fantes 9-bit og 11-bit prosessorer er ikke nyttig å vite i dag. Prosessorer i dag opererer med en byte som er 8-bit. Kompilatorer vi jobber med definerer int som 16, 32, eller 64-bit.

 

Vi jobber med implementasjoner, ikke standarder.

Lenke til kommentar

Det er ingen som sitter og skriver kode for teoretiske kompilatorer. Det er heller ingen som sitter og programmerer teoretiske prosessorer.

 

Det gjør ikke dine utsagn mer korrekte. Hvor vanskelig er det å fatte noe så elementært?

 

Visual C++ og GNU C++ bruker begge stack for å allokere variabler.

 

I minst *ett* tilfelle, slik allerede poengtert, vil definisjonen i *ditt* eksempel ikke nødvendigvis allokeres på stacken. Så hvorfor i huleste insisterer du på å dra inn allokeringsmodellen til implementasjonen, når den er *helt* uten betydning for det opprinnelige spørsmålet?

 

Det er derfor NYTTIG for alle nybegynnere å være klar over dette, og hvordan det fungerer.

 

OP lurte på semantikken til sizeof-operatoren. At du overhodet nevner allokeringsmodellen er helt *hinsides* -- det er overhodet *intet* poeng i det (uansett hvor nyttig det er å vite om allokeringsmodellene ellers). Det ville ha vært *uendelig* mye mer nyttig å fortelle at det er *typen* til operanden til sizeof som er av betydning, ikke *om* eller *hvor* det eventuelle objektet som uttrykket i operandren refererer til er allokert.

 

Vi jobber med implementasjoner, ikke standarder.

 

Nei, du jobber med å feilinformere folk, tydeligvis. Og attpåtil forsvarer du feilinformasjonen din, heller enn å innse at du har begått en feil, innrømme det, og bevege deg videre.

Endret av zotbar1234
Lenke til kommentar

Du er klar over at du kan bable og bable om teori og om hva standarden definerer i hytt og gevær,

 

... siden standarden definerer språket, synes jeg at det er *veldig* viktig "å bable" om hva den egentlig sier.

 

men om du skulle definert en egen standard for zotbar--, ditt framtidige språk,

 

Åhh... det er så søtt at du foreslår det. Men saken er at det har jeg allerede gjort. Og laget en referanseimplementasjon. Uten å måtte ta noe hensyn til underliggende hardware (det var et vesentlig poeng i arbeidet).

 

(...) så ville du ikke kommet noe sted som helst, fordi i praksis har det vært maskinvare og hva som faktisk funker som har styrt opphavet til standardene, ikke motsatt.

 

Du er klar over at man kan definere et språk A ift eksempelvis en virtuell maskin med akkurat de egenskapene man trenger? (f.eks. Java eller Python) Eller lage en referanseimplementasjon i et annet språk B, slik at kompilatoren A->B slipper å forholde seg til hvorvidt CHAR_BIT er 8 eller 9, og trenger kun å forholde seg til semantikken i språket B (heller enn den underliggende implementasjonen). Flere har hektet sine språk på mellomrepresentasjonen til gcc, f.eks.

 

Når det er sagt, vil jeg også legge til at jeg er rimelig sikker på at trådstarter fikk uendelig mer utbytte av det innlegget GeirGrusom skrev i starten, i motsetning til hva du prøver å bidra med i denne tråden.

 

Akkurat, ja. Feilinformasjon gir nå uendelig mer utbytte.

 

Har du vurdert å bli exphilforeleser?

 

Har du vurdert å basere kritikken din på tekniske argumenter i en teknisk diskusjon? Prøv å begynne der.

Lenke til kommentar

Flere ganger på dette forumet har folk fått problemer fordi de har allokert et array slik:

int myints[100];
int mysecondint;
myints[100] = 1000;

og funnet ut at dette fører til at mysecondint blir satt til 1000. Dette er også hele grunnøaget for stackoverflow angrep som baserer seg utelukkende på slike stackallokerte arrays uten bounds checking i C og C++ fører til at data vil overskrive påfølgende minneområde.

 

Det kan være at C++ standarden sier noe annet, men det er ikke slik det er implementert, og for meg er det ihvertfall da heller ikke relevant.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...