1

I am struggling with STL vectors in C++. I was compiling my project for only x64 for a time (actually for months), and everything was working fine, when I remembered that I need this to work on x86 machines also (Win32 DirectX application). Of course, the compiler errors came up instantly, that 16-bit aligned structures will not be aligned if for example passed to a function (those are the XMVECTOR and XMMATRIX, and XMFLOATA structures). I resolved those with success, and got my program running again, until I tried to load those structures into std::vectors by push_back() and emplace_back(). I give a short example code to be clear:

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
}
};

That is my structure, and I try to load several Armatures into a vector, like:

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() );
}

Full code here: http://pastebin.com/6D1wF4Vh

I tried setting __declspec_align(16) to everything, tried filling out the vector with Armature* and do aligned_malloc in the new operator, but the program exits every time with an Access violation reading location 0xFFFFFFF sometimes in the vector.h on the push_back function, sometimes while initializing an XMVECTOR struct, etc.

Am I missing something trivial here? Then I would be very grateful if someone could point out the obvious, or for any help.

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
  • This is extremely unclear. What, specifically, have you applied align(16) to? What is a concrete test-case that causes a runtime error? – Oliver Charlesworth Sep 04 '13 at 19:56
  • I see no `__declspec_align(16)` in the presented code. Are you trying to align the entire Armature type, or the specific fields within ? – WhozCraig Sep 04 '13 at 20:10
  • @Oli Charlesworth Sorry if I made myself unclear. I have tried to apply align(16) first to my structs, and after I became real desperate I tried setting it to every other veriable also. And I don't completely understand the second part of the question, sorry, my test case is when I call armatures.push_back(Armature()), then it randomly crashes either in the original "vector.h" or my Armature struct constructor when I want to initialize an XMVECTOR or XMMATRIX. – János Turánszki Sep 04 '13 at 20:12
  • @WhozCraig The presented code is just for a tip of how it looks, I have alreadytried aligning either the struct and the fields too. – János Turánszki Sep 04 '13 at 20:15
  • I can't see any reason that the above code snippets should "randomly crash" (other than the fact that that's an infinite loop!). I think you'd need to post a complete test-case that demonstrates this. – Oliver Charlesworth Sep 04 '13 at 20:15
  • 1
    Microsoft seem to recommend that you use XMFLOAT4 and XMFLOAT4X4 to store the values, and use XMVECTOR and XMMATRIX for calculations. Mostly due to exactly this issue I think. – jcoder Sep 04 '13 at 20:17
  • @Oli Charlesworth Then I must wait for someone who knows, because really, there is not much more happening. The entire "test-case" is just reading a file with operator>> and storing values of an armature described there, if everything is filled and there is still no end of file, it reads an other armature, and pushes back an empty one to armatures vector. Maybe there is something off with the DirectX specific structures, then so I will tag DirectX too. Thanks for the help though! :) – János Turánszki Sep 04 '13 at 20:19
  • @jcoder I will try that, then, hovewer it will be a huge pain in the arse, because there is so much more structures written like this. And strangely, I have ran into this error only with this. – János Turánszki Sep 04 '13 at 20:24
  • @JánosTuránszki: No, seriously, the bug is _in the code you haven't shown here_. The code here has no bugs. Please make a SSCCE so we can help you: http://sscce.org/ – Mooing Duck Sep 04 '13 at 20:26
  • To address the question you asked about aligned memory in the sequence for a vector, you'll be hard-pressed to do it without a custom allocator. Its tedious, but not mind-bending to accomplish. – WhozCraig Sep 04 '13 at 20:31
  • @Mooing Duck Should I post the standard library header file "vector.h" or the "DirectXMath.h", because the error is either there, or when calling XMMatrixIdentity() or XMVectorSet(0,0,0,0) from the struct constructor, you clearly would not want to get into that. I try jcoder's approach and return. – János Turánszki Sep 04 '13 at 20:35
  • 2
    @JánosTuránszki: The bug is in neither of those files. _The bug is in your code_. – Mooing Duck Sep 04 '13 at 20:38
  • Okay, then I copy the relevant parts from my code, before changing my entire code to XMFLOAT's. – János Turánszki Sep 04 '13 at 20:46
  • @MooingDuck http://pastebin.com/6D1wF4Vh I tried my best extracting the relevant part. It has the whole structure, the whole loading script, and an example file. – János Turánszki Sep 04 '13 at 21:00
  • @JánosTuránszki: You should cut that program down to the *simplest*, *complete* program that exhibits the problem, and then edit it into your question. – Oliver Charlesworth Sep 04 '13 at 21:42
  • Thank you all for trying to help! @jcoder pointed out the right answer to me, it was really a problem with my code, as XMVECTOR and XMMATRIX is not meant to be used in a structure, but XMFLOAT4 and XMFLOAT4X4 respectively and then they should be loaded and stored during runtime, calculation performed on XMVECTOR and XMMATRIX. jcoder Please answer this question and I will accept it (I will wait for two days). :) – János Turánszki Sep 04 '13 at 22:24

2 Answers2

2

Microsoft seem to recommend that you use XMFLOAT4 and XMFLOAT4X4 to store the values, and use XMVECTOR and XMMATRIX for calculations.

From the DirectXMath help : (http://msdn.microsoft.com/en-us/library/windows/desktop/ee418725(v=vs.85).aspx#basic_usage)

"However, often it is easier and more compact to avoid using XMVECTOR or XMMATRIX directly in a class or structure. Instead, make use of the XMFLOAT3, XMFLOAT4, XMFLOAT4X3, XMFLOAT4X4, and so on, as members of your structure. Further, you can use the Vector Loading and Vector Storage functions to move the data efficiently into XMVECTOR or XMMATRIX local variables, perform computations, and store the results. There are also streaming functions (XMVector3TransformStream, XMVector4TransformStream, and so on) that efficiently operate directly on arrays of these data types."

You can store the XMVECTOR and XMMATRIX types but specially if you store them in vectors and so on it can be very hard to get the alignment requirements right as the default allocators don't meet the requirements.

jcoder
  • 29,554
  • 19
  • 87
  • 130
0

while(!file.eof()) doesn't do what you think it does. eof() only returns true after trying to read past the end of file. Do you check the error state of file before calling push_back(...)? If not, the last element will be initialized with undefined values. And depending on your software, may, or may not, cause runtime errors.

  • It is clearly not the issue, because as I described, the code works perfectly well if I compile and run it for x64. Also, the real for loop in my program is nothing like that, I just created it so that people can see, that there will be much members of that vector. – János Turánszki Sep 04 '13 at 20:22
  • 1
    @JánosTuránszki How do you expect us to find the bugs in your code when your showing us _different_ buggy code? – Mooing Duck Sep 04 '13 at 20:25
  • The loop is irrelevant in this matter, because it just crashes on the first vector::push_back() operation. But I modified it just for you. – János Turánszki Sep 04 '13 at 20:31
  • `while(ThereAreMoreArmaturesToRead())` doesn't do what you think it does ;-) You *have* to check the state of `file` before using the values you read. This will not only catch reading past eof, but will also catch parse errors. – youdontneedtothankme Sep 04 '13 at 20:46
  • Look, the bottom line is, I am only loading anything, if the current line begins with a specified string or character, I got it checked in a switch. I even uploaded it already: pastebin.com/6D1wF4Vh (And thank you for trying to help!) – János Turánszki Sep 04 '13 at 21:15
  • Your parser is buggy. You have a buffer overflow when `file>>line` fails. And if that undefined memory location contains one of the magic characters in your switch statement, then your datastructure will be filled with bogous data. You may not have been bitten by this yet, but it *will* fail some day. Most likely when you are doing a presentation for your customer. – youdontneedtothankme Sep 05 '13 at 00:48