PDA

Visualizza la versione completa : [C++]SIZEOF(classe)??? Perchè queste dimensioni? D:


Redragon91
23-11-2011, 12:16
Ho un problema con la sizeof di alcune classi del mio progetto, spero voi possiate darmi una mano :P

Ecco l'OUTPUT delle sizeof:

sizeof(fattura): 44
sizeof(prodotti): 40
sizeof(persone): 88
sizeof(clienti): 100
sizeof(vendite): 20
sizeof(personale): 112
con i miei calcoli (semplice somma di dimensioni) le sizeof dovrebbero risultare leggermente diverse:
sizeof(fattura): 6+12+12+4+4+1=39
sizeof(prodotti): 6+25+4+4=39
sizeof(persone): 30+30+12+12=84
sizeof(clienti): PERSONE(quindi 88)+12=100 |OK|
sizeof(vendite): 6+6+4+4=20 |OK|
sizeof(personale): PERSONE(88)+17+4=109

A questo punto ho ipotizzato che le classi utilizzassero il modulo 4 per l'allocazione delle variabili ed ho ricalcolato in questo modo:

sizeof(fattura): |8|+12+12+4+4+1=41 |in realtà 44|
sizeof(prodotti): |8|+|28|+4+4=44 |in realtà 40|
sizeof(persone): |32|+|32|+12+12=88 |OK|
sizeof(clienti): PERSONE(quindi 88)+12=100 |OK|
sizeof(vendite): 6+6+4+4=20 |OK|
sizeof(personale): PERSONE(88)+|20|+4=112 |OK|

Quindi se il mio ragionamento è corretto a questo punto non capisco come calcolare le dimensioni errate...

Sperando che possiate aiutarmi, vi ringrazio in anticipo :)
PS:A seguire la dichiarazione delle classi.





class fattura
{
private:
char id[6], partiva[12],data[12];
float imptot,costivari;
bool pagato;
public:
//GET
char* getid();
char* getpartiva();
float getimptot();
bool getpagato();
char* getdata();
float getcostivari();
//SET
void setid(char*);
void setpartiva(char*);
void setimptot(float);
void setdata(char*);
void setpagato();
void setcostivari(float);
// COSTRUTTORE E DISTRUTTORE
fattura();
~fattura(){};

//FUNZIONI FRIENDs
friend void insfatt();
friend void visualfatt(char*);
friend fattura ricfatt(char*);
friend void regpag(char*);
friend void resoconto(char*);
friend void stampa(char*);
//OVERLOAD OPERATORE ESTRAZIONE BIT cout<<F equivale alla chiamata di operator<<(cout,F);
friend ostream& operator<< (ostream &out, fattura &F);


};


class prodotti{
private:
char idprod[6], nome[25];
float punit;
int giacenza;

public:
char* getidprod();
char* getnome();
float getpunit();
int getgiac();
void setidprod(char*);
void setnome(char*);
void setpunit(float);
void setgiac(int);
prodotti();
prodotti(const prodotti& );
~prodotti(){};

//FUNZIONI MAIN
friend void insprod();
friend void visualprod();
friend int modprod(char*);
friend bool acquisto(char*,int);
friend bool modgiac(char*,int);
friend prodotti ricprod(char*);
friend ostream& operator<< (ostream&, prodotti &);

};


class persone{
protected:
char nomecognome[30],residenza[30], telefono[12], fax[12];
public:
// CLASSE VIRTUALE PURA non è possibile inizializzare nessun oggetto
// di questa classe
virtual void visual()=0;
virtual bool mod(char*)=0;
virtual int ins()=0;

char* getnomcogn();
char* getresid();
char* gettel();
char* getfax();

void setnomcogn(char*);
void setresid(char*);
void settel(char*);
void setfax(char*);

persone();
~persone(){};
};


class clienti:public persone{
private:
char piva[12];
public:
char* getpiva();
void setpiva(char*);
clienti();
clienti(const clienti&);
~clienti(){};
// FUNZIONI VIRTUALI
int ins(); //restituisce -1 in caso di errore, 0 se si è svolta correttamente la funzione
void visual();
bool mod(char*); //restituisce 0 se non ha trovato riscontri di partita iva, 1 se ha modificato un prodotto
// FUNZIONI FRIEND
friend clienti riccli(char*); //restituisce l'elemento ricercato nei clienti
friend ostream& operator<< (ostream&, clienti&); //utilizza lo stream di output equivale a richiamare operator<<(cout,C);

};



class vendite{
private:
char idf[6], idp[6];
int quant, aliq;


public:
char* getidf();
char* getidp();
int getquant();
int getaliq();
void setidp(char*);
void setidf(char*);
void setquant(int);
void setaliq(int);
vendite();
~vendite(){};

void insvend(char*,char*,int,int);
void visualvend(char*);


};


class personale:public persone{
private:
char codfisc[17];
float stipendio;
public:
char* getcontr();
char* getcodfisc();
float getstipendio();
void setcontr(char*);
void setcodfisc(char*);
void setstipendio(float);
personale();
~personale(){};

//FUNZIONI VIRTUALI
int ins(); //-1 in caso di errore, altrimenti restituisce 0
void visual();
bool mod(char*); //0 se non modifica e quindi non trova riscontri di codicefiscale, 1 se viene eseguita la modifica
//FUNZIONI FRIENDs
friend personale ricpers(char*);
//OVER. OPERATORE
friend ostream& operator<< (ostream&, personale&);

};

oregon
23-11-2011, 12:28
Inserisci in testa

#pragma pack(1)

Redragon91
23-11-2011, 12:30
questo serve ad allineare in "modulo 1" giusto?
se dovessi ometterlo le classi si allineerebbero in modulo 4 (se ricordo bene!) ma quali dimensioni modifica? char? bool? giusto? (anche perchè le altre sono già allineate in mod4 ad es: int,float,double ecc..ecc...



grazie mille :D

oregon
23-11-2011, 12:38
Perché l'allineamento di default è di 4 byte

Tieni presente che un allineamento ad 1 può ridurre le prestazioni complessive.

La char[6] diventa di 8, il bool di 4, ma dipende anche dall'ordine in cui poni le variabili ... senza pragma pack se avessi scritto

float imptot,costivari;
char partiva[12],data[12];
char id[6];
bool pagato;

sarebbe stato diverso

Redragon91
23-11-2011, 12:42
grazie, come immaginavo :)

Ipotizzando che l'allineamento è a 4 giusto?

la classe fattura passa da 39 a 44 poichè aumenta char id[6]->ad 8 byte e bool p; da 1 a 4 byte? 39+5=44 e ci siamo!

invece la classe PRODOTTI ha un comportamento alquanto strano...da 39 passa a 40 ma...
id[6]->8
nome[25]->28 quindi
quindi +5...ma in realtà non viene 44 ma 40! XD e quindi qui applica un allineamento globale da 39 a 40...perchè non lo fa anche con la classe fattura?

forse perchè in fattura ha 2 tipi di variabili da allineare ed invece a prodotti solo un tipo?

che confusione :S

sapresti darmi delle delucidazioni?
:cry:

oregon
23-11-2011, 13:12
Non devi aggiungere a tutti i campi ...

Ma prima una curiosità ... a cosa ti serve gestire questo tipo di informazioni?
Utilizzando le classi, non ha senso badare ai byte e alla grandezza di ogni dato.

E poi ... perché usi i char[...] e non le classi string?

E usando i char hai tenuto presente il terminatore?

Redragon91
23-11-2011, 13:20
Originariamente inviato da oregon
Non devi aggiungere a tutti i campi ...

Ma prima una curiosità ... a cosa ti serve gestire questo tipo di informazioni?
Utilizzando le classi, non ha senso badare ai byte e alla grandezza di ogni dato.

E poi ... perché usi i char[...] e non le classi string?

E usando i char hai tenuto presente il terminatore?

si ho tenuto presente del terminatore ;) uso i char per una comodità personale e le sizeof mi servivano per capire il funzionamento dell'allineamento...ho un esame imminente XD

philbert
23-11-2011, 15:47
Originariamente inviato da Redragon91
si ho tenuto presente del terminatore ;) uso i char per una comodità personale e le sizeof mi servivano per capire il funzionamento dell'allineamento...ho un esame imminente XD

La sizeof di una classe risente sì della policy di alignment , che tra l'altro può cambiare da un compilatore all'altro.

Ma è influenzata anche da altri fattori (es l'ordine della variabili all'interno della classe, la presenza di funzioni virtuali che aggiungono alla classe 4 bytes che puntano alla virtualtab) quindi può tranqullamente dare risultati non perfettamente calcolabili a priori senza grande sforzo o senza conoscere in dettaglio le specifiche di alignement del compilatore...

cmq in bocca la lupo per l'esame!
Ph

Redragon91
23-11-2011, 15:51
Originariamente inviato da philbert
La sizeof di una classe risente sì della policy di alignment , che tra l'altro può cambiare da un compilatore all'altro.

Ma è influenzata anche da altri fattori (es l'ordine della variabili all'interno della classe, la presenza di funzioni virtuali che aggiungono alla classe 4 bytes che puntano alla virtualtab) quindi può tranqullamente dare risultati non perfettamente calcolabili a priori senza grande sforzo o senza conoscere in dettaglio le specifiche di alignement del compilatore...

cmq in bocca la lupo per l'esame!
Ph

grazie per il chiarimento!
crepi! :)

Loading