• Advertisement
Sign in to follow this  

memory alignment

This topic is 3634 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all few months ago I had one issue (bug) when I was sending data over network. On some rare occasion it seemed that struct that I sent as message body didn't arrived all well. It had ints, chars etc. I resolved that changing struct to BYTE array, memcpy-ing bytes to int and everything was ok. I knew that it must be something with alignment of memory but I didn't know any better way to resolve the problem. Not so long ago I stumbled upon align command. Didn't even know that there is something like that. So easy: __declspec(align(1)) typedef struct and works. Question: What is the right way to align struct where you have several integers, and several bytes? Should I put align(sizeof(int)) or align(1)? Thanks in advance

Share this post


Link to post
Share on other sites
Advertisement
The compiler can rearrange and introduce padding in a struct in any way it sees fit. So, it is indeed quite unsafe to send that struct over the network or to a file.
Better than enforcing a specific memory alignment, you can tell the compiler not to shuffle the struct, but let it keep the layout you specified. You can do this by surrounding it with two pragmas:

#pragma pack(push,1)
struct MyStruct {
int a;
char b;
long c;
};
#pragma pack(pop)

Share this post


Link to post
Share on other sites
Of course, the #pragma solution begins to fall down as soon as you need your code to be compiled on more than one compiler (which may well be never), since #pragma directives are compiler specific and conforming compliers are required to silently ignore ones they don't support.

Be aware of this if multicompiler support is something you currently care about.

A more generalized solution is to implement some kind of serialization mechanism that will serialize instances of class types into a packed byte buffer. There are a number of ways to do this, from library solutions like Boost.Serialize, to writing it manually, to preprocessing and code generation tricks, et cetera.

Share this post


Link to post
Share on other sites
Thank guys for your replies.

So generally is it safe to:

#pragma pack(push,1)
struct MyStruct {
int a;
char b;
long c;
};
#pragma pack(pop)

if I work only on one compiler?

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
And if that one compiler is VS, yes. It should be relatively safe.


It is [smile]
thanks again

Share this post


Link to post
Share on other sites
If you are writing structs in binary format directly to files/sockets/etc., get in the habit of adding a compile-time assert to verify that the size is the size you expect.

e.g.:

struct MyStruct {
int a;
char b;
long c;
};
C_ASSERT(sizeof(MyStruct) == 9); // or whatever

Then if packing/alignment or other compiler optimizations kick in you'll know about at compile time.

C_ASSERT is a Windows thing. Boost also has BOOST_STATIC_ASSERT.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anon Mike
If you are writing structs in binary format directly to files/sockets/etc., get in the habit of adding a compile-time assert to verify that the size is the size you expect.

e.g.:

struct MyStruct {
int a;
char b;
long c;
};
C_ASSERT(sizeof(MyStruct) == 9); // or whatever

Then if packing/alignment or other compiler optimizations kick in you'll know about at compile time.

C_ASSERT is a Windows thing. Boost also has BOOST_STATIC_ASSERT.


I have two bytes for crc check. [smile]

Share this post


Link to post
Share on other sites
Or, if you don't want to clutter your code with pragmas and such, you can fix the problem. Since you didn't say how you are actually receiving the structs, I can't really say what the problem was, except that it sounds strange. Did you send the struct by using sizeof(MyStruct) to get the struct's size? Or did you just sum up the component sizes by hand?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement