Kezdőoldal » Számítástechnika » Programozás » Tömb mérete miért marad 4?

Ozmium42 kérdése:

Tömb mérete miért marad 4?

Figyelt kérdés

Üdv!


Tömbökkel, pointerekkel, malloc, calloc, realloc függvényekkel kísérletezek. Egy olyan programot szeretnék írni, ami növelgeti egy tömb számára lefoglalt memóriát, és a felszabadult helyre egy számot rak. Ez eddig kész is van, de arra gondoltam, jó lenne annyival tovább bonyolítani, hogy a tömb mérete ne növekedjen minden ciklusban, hanem csak akkor, ha megtelik (ekkor több, mint egy sizeof(int) területet lefoglal), és ezt a tömb elemszámán keresztül lehetne ellenőrizni. Sajnos bármekkora memóriát foglalok le, és akárhány elemet rakok a tömbbe, a sizeof() eredménye mindig négy. Gondolom azért, mert a tömb neve az első elemére mutató pointer. De akkor honnan tudjam meg, hány elemmel van éppen feltöltve a tömböm?


Itt az utolsó működőképes részlet, bár nem kell, hogy megírjátok helyettem, csak valami ötlet kellene az *x méretének meghatározására:


[link]


2014. dec. 24. 16:26
 1/8 anonim ***** válasza:

Ha jól sejtem, C.


A tömb méretét kénytelen leszel magad nyilvántartani, mivel csak egy pointered van, a compiler pedig ebből nem fogja tudni, hogy az mekkora területre mutat majd runtime.


Egyébként az általad leírtak mentén működik a Java ArrayList típusa is.

2014. dec. 24. 16:48
Hasznos számodra ez a válasz?
 2/8 anonim ***** válasza:

struct dynamic_array {

int *data;

size_t size;

size_t allocated;

};


Mondjuk jelentse a size azt, hogy éppen mennyi van benne, az allocated meg azt, hogy éppen mekkora.

Szerintem kész, már csak írni kell hozzá függvényeket.

2014. dec. 24. 17:53
Hasznos számodra ez a válasz?
 3/8 A kérdező kommentje:
Igen, C.
2014. dec. 24. 17:55
 4/8 A kérdező kommentje:

Az a furcsa, hogy ha olyat csinálok, hogy:


int x[5] = {1,2,3,4,5}


akkor sizeof(x) == 20, ami ugye 5*sizeof(int)-nek felel meg. Azt vártam, hogy pointeres tömbnél is le lehet így kérdezni elemek számát. Nem világos számomra, hogy mi a különbség a kettő között.

2014. dec. 24. 18:50
 5/8 uno20001 ***** válasza:
100%

A statikus tömb (int a[] = {1, 2, 3};) elemszámát (sizeof(a)/sizeof(a[0]) azért tudod lekérdezni, mert az fordításkor értékelődik ki.

Amennyiben dinamikus tömböket használsz, kénytelen vagy számon tartani a tömböd méretét, mivel máshogyan nem tudod lekérdezni az elemszámot.

2014. dec. 24. 19:12
Hasznos számodra ez a válasz?
 6/8 A kérdező kommentje:
Köszönöm a válaszokat.
2014. dec. 24. 22:05
 7/8 anonim ***** válasza:

Nem teljesen pontos amit uno20001 írt. Azért kapsz 4-et mert nem tömbnek hanem pointernek deklaráltad a változód, aminek a mérete 4 bájt 32 biten, 8 bájt 64 biten.


A sizeof() függvény különbséget tesz pointer és tömb között, kivéve ha a tömb egy függvény deklarációjában van, mert akkor automatikusan helyettesíti a fordító azt egy pointerrel. Sajnos pointerből viszont nem lehet tömb típust csinálni, csak a tömb szintaktikáját használni, tömböt imitálva ezzel.


A sizeof() valóban, általában fordításkor értékelődik ki, de nem mindig ez a helyzet. C99-től a tömb méretét nem csak konstanssal de változóval is meg lehet adni, az így deklarált tömböket a program számon tartja és a sizeof() mindig futás időben értékeli ki a méretüket.


Erre példát is ad a C standard dokumentációja:


#include <stddef.h>

size_t fsize3(int n)

{

char b[n+3]; //variable length array

return sizeof b; //execution time sizeof

}

int main()

{

size_t size;

size = fsize3(10); // fsize3 returns 13

return 0;

}


Ha lekérdezed egy tömb típusát, meg tudod nézni minek tekinti a fordító:

int foo[5]; //foo típusa: int[5]

void bar(int foo[5]) {} //foo típusa: int *

int bar 5; int foo[bar]; //foo típusa: int[(sizetype)(bar)]


A típustól függ hogy mit fog visszaadni a sizeof().


Fun fact: pár kivételes esettől eltekintve (pl sizeof), a fordító a tömböket pointerekké konvertálja h az nem a kifejezés bal oldalán áll, ezért ezek mindegyik helyes és egyenértékű egy kifejezés jobb oldalán: tomb[5], *(tomb+5), *(5+tomb), 5[tomb]


Szintaktikai hibák:

int tomb[5];

tomb++; /*nem értelmezhető*/

tomb=tomb+1; /*nem lehet (int *)-t tomb[5]-é konvertálni*/

int* tomb2=tomb; /*helyes tomb[5]-t lehet (int *)-é konvertálni*/

tomb2++; /*helyes*/

int bar=tomb2[2]; /*helyes*/

void foo(int tomb[]) {tomb++;} /*helyes mert függvény deklarációban automatikusan pointer lesz belőle*/


A *alloc függvények pointereket adnak vissza, ezek nem tömbök, csak mutatók amik egy lefoglalt területre mutatnak, ezért a sizeof() a mutató méretét fogja visszaadni és nem a lefoglalt terület méretét. Mutatót nem lehet tömbbé alakítani, ezért neked kell számon tartanod egy változóban azt, hogy mennyit foglaltál le.


Valójában a lefoglalt terület méretét számon tartja a program, amihez egyébként hozzá is lehet férni, de ez nincs specifikálva, és platform és fordító függő. Nem véletlenül tudja a free() parancs mennyit kell felszabadítania.

[link]

[link]

[link]

2014. dec. 25. 05:31
Hasznos számodra ez a válasz?
 8/8 uno20001 ***** válasza:
#7: Köszönöm a pontosítást!
2014. dec. 25. 11:39
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!