2009-11-17 2 views
1

J'ai une classe qui va comme ceci:Pourquoi mon objet occupe-t-il 64 octets et non 32?

class myType 
{ 

    union { 
     float data[4]; 
     other_vector4_type v 
    } ; 
    typedef union { 
     float data[4]; 
     other_vector4_type v 
    } myType-internal_t; 

<various member functions, operator overloads> 

} 

Maintenant, je veux utiliser ce type dans mon vertex buffer, mais le sizeof() est pas comme prévu. J'ai aligné la classe à 16 octets.

sizeof(myType) cède 64.

sizeof(myType::myType-internal_t) rendements 32.

J'ai lu assez peu d'articles sur l'alignement des données, mais je ne sais pas où j'utilise des données supplémentaires. J'ai essayé d'enlever le constructeur personnalisé, mais il reste le même, l'échange du mot-clé de classe pour struct ne change pas non plus (je ne comprends pas ce que c'est, car il arrive!)

Ceci est ennuyeux, je ' J'utiliserai le type interne pour le moment car je ne toucherai pas souvent aux données, mais ce serait bien que la classe fonctionne comme je le souhaite.

+2

Dites-nous à quoi ressemble other_vector_type. – bmargulies

+1

Vous devriez clarifier la partie code de votre question ... –

+2

Un cas de test complet (qui compile et utilise une syntaxe correcte) aiderait à résoudre le vrai problème. –

Répondre

2

Un compilateur C++ peut faire struct 128 octets pour tout ce qu'il prend en charge. La taille des structures/unions n'est pas définie par la norme C++. Cependant, la plupart des compilateurs ont un attribut __PACKED non standard que vous pouvez ajouter à la déclaration d'une structure et il ne prendra que la quantité exacte d'octets dont il a besoin

+0

Il y aura généralement un coût associé à l'emballage. Il y a une raison pour laquelle vous devez ajouter explicitement l'attribut. Vous ne devez donc l'utiliser que s'il y a une raison pour laquelle vous devez supprimer tout le remplissage (c'est-à-dire l'aligner avec une structure de noyau interne, ou un paquet pour le transport par câble). –

1

Si vous avez des fonctions virtuelles dans votre classe, vos objets seront plus gros que le type interne à cause du pointeur vtable.

BTW "struct {" est la même chose que dire "class {public:"

+0

merci siukurnin! – Sorlaize

1

J'imagine que vous aurez un pointeur vtable défini pour vos objets. Soit parce que vous avez RTTI activé ou une méthode virtuelle (y compris le destructor) ajoutera une vtable

http://en.wikipedia.org/wiki/Virtual_method_table

En règle générale, le compilateur crée un vtable pour chaque classe. Lorsqu'un objet est créé, un pointeur vers cette vtable, appelé pointeur de table virtuelle ou vpointer, est ajouté en tant que membre caché de cet objet (devenant son premier membre à moins qu'il ne soit le dernier [2]). Le compilateur génère également du code "caché" dans le constructeur de chaque classe pour initialiser les vpointers de ses objets à l'adresse du vtable correspondant.

1

Je viens compilé

#include <xmmintrin.h> 
#include <iostream> 

struct myType 
{ 
    union { 
     float data[4]; 
     __v4sf v; 
    }; 
    typedef union { 
     float data[4]; 
     __v4sf v; 
    } myType_internal_t; 
}; 

int main() { 
    std::cout << sizeof(myType) << std::endl; 
    std::cout << sizeof(myType::myType_internal_t) << std::endl; 
} 

Et le résultat est:

16 
16 

gcc sur un arc de 64 bits. Comme prévu. "__v4sf" est un type vectoriel composé de quatre flottants. Donc, le problème est probablement dans votre "other_vector_4_type". Peut-être qu'il est polymorphe et virtuel et contient deux vtables? Et vous utilisez plus de fonctions virtuelles dans "myType" qui augmentent encore sa taille? Le problème peut être lié à votre compilateur ou à l'architecture aussi.

Questions connexes