2013-09-04 2 views
1

Je suis aux prises avec des vecteurs STL en C++. Je compilais mon projet pour seulement x64 pendant un certain temps (en fait pendant des mois), et tout fonctionnait bien, quand je me suis souvenu que j'avais besoin de cela pour travailler aussi sur des machines x86 (application Win32 DirectX). Bien sûr, les erreurs du compilateur sont apparues instantanément, les structures alignées de 16 bits ne seront pas alignées si elles sont par exemple passées à une fonction (ce sont les structures XMVECTOR et XMMATRIX, et XMFLOATA). J'ai résolu ces problèmes avec succès, et j'ai redémarré mon programme, jusqu'à ce que j'essaie de charger ces structures dans std :: vectors par push_back() et emplace_back(). Je donne un court exemple de code pour être clair:Impossible d'accéder aux membres alignés 16 bits de std :: vector?

struct Armature 
{ 
string name; 
int index; 
//{...} There are much more 
XMVECTOR translation; //Four 32 bit floating point components aligned on a 16 byte 
// boundary and mapped to hardware vector registers 
XMVECTOR rotation; 
XMVECTOR scale; 
XMMATRIX world; //it is like 4 XMVECTORs (4*4 matrix) 

Armature(){ 
//I initialize everything here 
} 
}; 

C'est ma structure, et j'essaie de charger plusieurs Armatures dans un vecteur, comme:

std::vector<Armature> armatures; 

while(ThereAreMoreArmaturesToRead()){ //roughly like this, I just parse a file and load up the information from there to fill out my Armature structure 
armatures.push_back(Armature()); 
} 

code complet ici: http://pastebin.com/6D1wF4Vh

J'ai essayé de mettre __declspec_align (16) à tout, j'ai essayé de compléter le vecteur avec Armature * et done align_malloc dans le nouvel opérateur, mais le programme quitte à chaque fois avec un emplacement de violation de violation d'accès 0xFFFFFFF parfois dans le vecteur. la fonction push_back, parfois lors de l'initialisation d'une structure XMVECTOR, etc.

Ai-je manqué quelque chose de trivial ici? Ensuite, je serais très reconnaissant si quelqu'un pouvait signaler l'évidence, ou pour toute aide.

+0

Ceci est extrêmement peu clair. À quoi avez-vous spécifiquement appliqué align (16)? Qu'est-ce qu'un cas de test concret qui provoque une erreur d'exécution? –

+0

Je ne vois pas de '__declspec_align (16)' dans le code présenté. Essayez-vous d'aligner tout le type d'armature, ou les champs spécifiques à l'intérieur? – WhozCraig

+0

@Oli Charlesworth Désolé si je me suis rendu flou. J'ai essayé d'appliquer align (16) d'abord à mes structures, et après que je suis devenu vraiment désespéré, j'ai essayé de le mettre à tous les autres vérifiables aussi. Et je ne comprends pas complètement la deuxième partie de la question, désolé, mon cas de test est quand j'appelle armatures.push_back (Armature()), puis il se bloque aléatoirement dans le "vecteur" original.h » ou mon constructeur struct Induit quand je veux initialiser un XMVECTOR ou XMMATRIX. –

Répondre

2

Microsoft semble vous recommander d'utiliser XMFLOAT4 et XMFLOAT4X4 pour stocker les valeurs et utiliser XMVECTOR et XMMATRIX pour les calculs.

De l'aide DirectXMath: (http://msdn.microsoft.com/en-us/library/windows/desktop/ee418725(v=vs.85).aspx#basic_usage)

« Cependant, il est souvent plus facile et plus compact pour éviter d'utiliser XMVECTOR ou XMMATRIX directement dans une classe ou une structure plutôt utiliser la XMFLOAT3, XMFLOAT4, XMFLOAT4X3. , XMFLOAT4X4, et ainsi de suite, en tant que membres de votre structure.En outre, vous pouvez utiliser les fonctions Vector Loading et Vector Storage pour déplacer efficacement les données dans les variables locales XMVECTOR ou XMMATRIX, effectuer des calculs et stocker les résultats. (XMVector3TransformStream, XMVector4TransformStream, etc.) qui fonctionnent efficacement directement sur les tableaux de ces types de données. " Vous pouvez stocker les types XMVECTOR et XMMATRIX mais surtout si vous les stockez dans des vecteurs et ainsi de suite il peut être très difficile d'obtenir les exigences d'alignement correctement car les allocateurs par défaut ne répondent pas aux exigences.

0

while(!file.eof()) ne fait pas ce que vous pensez qu'il fait. eof() renvoie uniquement trueaprès en essayant de lire après la fin du fichier. Vérifiez-vous l'état d'erreur de file avant d'appeler push_back (...)? Sinon, le dernier élément sera initialisé avec des valeurs indéfinies. Et en fonction de votre logiciel, peut, ou non, provoquer des erreurs d'exécution.

+0

Ce n'est clairement pas le problème, car comme je l'ai décrit, le code fonctionne parfaitement bien si je compile et l'exécute pour x64. De plus, la vraie boucle for de mon programme n'est rien comme ça, je l'ai juste créée pour que les gens puissent voir, qu'il y aura beaucoup de membres de ce vecteur. –

+1

@ JánosTuránszki Comment vous attendez-vous à ce que nous trouvions les bogues dans votre code lorsque vous nous montrerez le code buggy _different_? –

+0

La boucle n'est pas pertinente dans ce cas, car elle se bloque juste sur la première opération vector :: push_back(). Mais je l'ai modifié juste pour toi. –