Sizeof d'un classe en C++ [Résolu]

Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
- - Dernière réponse : MahaYassine
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
- 4 févr. 2010 à 11:48
Bonjour,

J'ai un problème avec le C++ sous Solaris. Au fait j'essaye de faire un sizeOf d'une classe mais ça me retourne pas la taille exacte. Le résultat c'est un nombre mutliple de 8. Cela est dû au fait que le compilateur sous Solaris impose un alignement de 8 dans lors réservation de la mémoire.
Exemlpe :

[b]#include

class A
{
public:

char ch[13];
int nb;
char c1;
char c2;
A(){}//constructeur

};

int main()
{
std::cout<<sizeof(A)<<std::endl;
return 0;
}/b

Le résultat obtenu est 24 à la place de 19

Y a t-il une solution pour rendre cet alignement à 1 ou une autre alternative à part l'utilisation du sizeOf ?!! Sachant que mettre #pragma pack(1) n'a pas d'effet sur les classes.

Merci !!
Afficher la suite 

17 réponses

Meilleure réponse
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
3
Merci
A essayer (je ne fais plus de C++ depuis des lustres):

Tu déclares en #pragma pack(1) une struct hors de ta classe:
typedef struct _MEMBRESA {
char ch[13];
int nb;
char c1;
char c2;
} MEMBRESA;

Dans la classe:
class A
{
public:
MEMBRESA mbrs;

A(){} //constructeur
};

Tout de meme une drole d'idée de vouloir des non alignés:
- Soit on devra accéder au 'int' octet par octet.
- Soit c'est le crash si un admin system règle le system sur non récup des exceptions CPU #ALIGN (réglable sous Windows, je ne sais pas pour Unix). Sur CPU Alpha c'était non réglable donc badaboum à tout coup.

ciao...
BruNews, MVP VC++

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 135 internautes nous ont dit merci ce mois-ci

Commenter la réponse de BruNews
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Statut
Membre
Dernière intervention
10 juillet 2018
4
0
Merci
salut,

pourquoi 19 ?
A(){}//constructeur, ça a aussi une taille !!!!
Commenter la réponse de fregolo52
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
Ah oui désolé 19 c'est sans le constructeur, j'ai complètement oublié que je l'ai ajouté après !!

[b]#include

class A
{
public:

char ch[13];
int nb;
char c1;
char c2;

};

int main()
{
std::cout<<sizeof(A)<<std::endl;
return 0;
} /b

Le résultat obtenu est 24 à la place de 19
Commenter la réponse de MahaYassine
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Statut
Membre
Dernière intervention
10 juillet 2018
4
0
Merci
je ne sais pas quelle est la différence entre une classe et une structure dans ce cas précis.

As-tu déplacé le int (en 1er ou en dernier) pour voir si ca fait toujours 24 ?
Commenter la réponse de fregolo52
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
Oui j'ai déplacé le int au début et j'ai même essayer d'autres combinaisons. Et au meilleur des cas j'ai obtenu 20 mais pas 19. Avec les classes contenant des constructeurs ou qui héritent d'autres classes le #pragma pack(1) ne fonctionne pas !!
Commenter la réponse de MahaYassine
Messages postés
3835
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
84
0
Merci
je ne sais pas quelle est la différence entre une classe et une structure dans ce cas précis.

En C++, classe et structure sont strictement identiques. Une structure est une classe dont la visibilité par défaut est public, au lieu de private.

Est-tu sur que ce n'est pas la taille exact de ta classe appliqué à cet environnement ? Sous Solaris, les types n'ont pas la même taille, ni la même la taille de structure ou de classe (qui varient beaucoup en fonction de certains critères comme la présence ou non de virtual, d'héritage, etc...).
De plus, est-ce vraiment gênant ?

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Commenter la réponse de cptpingu
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Statut
Membre
Dernière intervention
10 juillet 2018
4
0
Merci
reste encore un test avec gcc (super dégueulasse) : -fpack_struct
mais adieu les perfs.

si tu replaces ta classe par une struct et que tu as toujours 20 avec #pragma pack(1), c'est que c'est l'OS qui ne veut pas aligner à 1. et donc tu n'auras jamais 19.
Commenter la réponse de fregolo52
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
@CptPingu: oui je confirme que j'ai 24 à la place de 19. Je ne peux pas la changer en struct car je compte ajouter un constructeur par la suite. Et je veux avoir la taille exacte c'est important et obligatoire pour mon cas.

@fregolo52: avec #pragma pack(1) j'ai bien mon 19 sauf que après je compte ajouter un constructeur et cette option ne fonctionne plus dans ce cas. Pour le -fpack_struct je pourrais pas l'utiliser puisque on va dire adieu au perfs et alors là mon patron risque de me virer !!
Commenter la réponse de MahaYassine
Messages postés
3835
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
84
0
Merci
Je ne peux pas la changer en struct car je compte ajouter un constructeur par la suite.

Encore une fois en C++ => class == struct (mise à part la visibilité par défaut)

class Toto
{
  int a
public:
  Toto() {}
};

Est strictement équivalent à:
struct Toto
{
  Toto() {}
private:
  int a
};


_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Commenter la réponse de cptpingu
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
Ok merci pour l'info. ça je le découvre pour la première fois !

et donc t'as pas de solution à proposer pour ça ?
Commenter la réponse de MahaYassine
Messages postés
3835
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
10 juin 2019
84
0
Merci
et donc t'as pas de solution à proposer pour ça ?

Malheureusement, non :(. Si tu trouves une réponse, n'hésite pas à la poster.

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Commenter la réponse de cptpingu
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
D'accord !!

En tout cas merci pour l'aide comme même!
Si j'ai du neuf je te fait signe !!
Commenter la réponse de MahaYassine
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
0
Merci
char ch[13];
int nb;
char c1;
char c2;

fait 24, ben c'est fort heureux, merci le compilo.
Il a retranscrit n:
char ch[16];
int nb;
char c1;
char c2;
char dummy[2];

Remis en propre ça donnerait;
int nb; // ALIGN 4 garanti en compil 32, else 8
char ch[13];
char c1;
char c2;
char dummy; // ce que tu as omis en compil 32
serait char dummy[7]; si compil 64

Imagine ton code lisant ou écrivant un DWORD (nb) avec un align != 4, serait une cata en perfs.

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Messages postés
21054
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
0
Merci
OUPS, tapé trop vite:
serait char dummy[5]; si compil 64

ciao...
BruNews, MVP VC++
Commenter la réponse de BruNews
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Statut
Membre
Dernière intervention
10 juillet 2018
4
0
Merci
Pour reprendre les exmples précédents : essaie de gérer toi-même le padding.
class Toto
{
  int a;
  char c;

  Toto() {}
};

class Toto
{
  Toto() {}

  int a;
  char c;
};


je n'ai pas testé, mais peut-etre que le sizeof du 1er va donner 12 (a cause du char entre le int et le constructeur) et le 2e donnera 9, si compilation 32bit.

je pense qu'il aut que tu aides le compilo a combler les trous.
Commenter la réponse de fregolo52
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
@BruNews : Très bon raisonnement!!
Oui en changeant l'ordre de déclaration des attributs de la classe, on aura une amélioration de point de vue allocation de mémoire. Mais comme j'ai précisé avant j'ai une contrainte ===> j'ai pas le droit ni de changer l'ordre de déclaration des attributs ni d'en ajouter d'autres.
Je commence à détester mon compilateur !!

@fregolo52 : J'ai essayé ta proposition mais dans les deux cas on obtient 8 pas un 9. Mon compilo est 64bit je pense.
Commenter la réponse de MahaYassine
Messages postés
31
Date d'inscription
mercredi 26 mars 2008
Statut
Membre
Dernière intervention
4 février 2010
0
Merci
Oui c'est bon ça marche l'idée du struct !!
Reste maintenant à convaincre mon patron !!

merciiiiiiiiii !!
Commenter la réponse de MahaYassine