Link to home
Start Free TrialLog in
Avatar of devoured_elysium
devoured_elysium

asked on

I'd like to know how structs are stored in memory

Hello. I'd like to know how structs are stored in memory. For example, if i have the following struct:

struct A {
    int _a;
    int _b
}

will it be safe to assume that if an instance of struct A is allocated at memory offset 100, the variable _a will be stored at 100 and variable _b will be at 100 + sizeof(int) ?
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image


For the most part, yes.  There are often compiler options to regulate alignment that results in each item starting on a character, 16-bit, 32-bit, or 64-bit boundary.  But the default alignment is usually in line with sizeof (int).

Good Luck,
Kent
>> the variable _a will be stored at 100

That is guaranteed, yes. The first struct field always starts at the start address of the struct.


>> variable _b will be at 100 + sizeof(int)

Since int is the standard type, this will be true on most platforms, but there's no guarantee. The compiler might add padding between struct fields if needed.

Note that padding can be added between the fields, and at the end of the struct. Usually padding is added to align the fields on word boundaries.
Avatar of devoured_elysium
devoured_elysium

ASKER

If I know the struct declaration, am I able to read the values directly from memory? I mean, if I have a structure defined in project A which is like that one above, and I have one instance which I read from memory and send to another project(called project B), will I be able to just by pointer arithmetic read the contents of the struct, without ever defining it?

Thanks
>> will I be able to just by pointer arithmetic read the contents of the struct, without ever defining it?

If you know which padding was added, and if the other platform uses the same data type sizes and definitions, then that should work yes.

But, I would suggest to use an encoding to transfer data between systems, and then decode it on the target system into its own struct.

To do that, you'll have to know what the alignment is so that you know how much padding may be between the data items.

If the default alignment is a 32-bit boundary, note that defining and item as a char will cause the next item to move to the 32-bit boundary.  If you declare consecutive items as *char*, it doesn't matter that it will fit, the second one will be moved to the next alignment boundary.

The only way to be sure how and where the item will align will be to control the alignment yourself (via compiler options or #pragma statements) or to compute them yourself.  The code below should tell you what the alignment size is.  Your only challenge beyond that is to note which items are larger than this and note that they will align on a multiple of this value.


Good Luck,
Kent


struct
{
  a   char;
  b   char;
} aligntest_t;

aligntest_t Test;

  printf ("alignment is %d bytes\n", &Test.b - &Test.a);



Kent
Hm, I still don't get one thing. The way Windows will pad the struct will be ALWAYS the same on the same computer, or will depend on how full the memory currently is, etc? If I see that windows will right now put the two ints together without padding them for an instance of my struct, is it correct to assume it will do the same for another 100?
ASKER CERTIFIED SOLUTION
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial

The alignment is a compile time decision, controller by you (as compiler options) or the source code.  The amount of memory available at run time has no bearing on alignment.


Kent
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
May I ask why you gave a B grade ? That usually means that something is missing in the answers and/or that something is still unclear. If that's the case, then please do not hesitate to ask for clarification where needed.
I am sorry, I just gave points and skimmed through the page. If there's a way to still change it, I'll do it. Is there?
No worries. I just wanted to make sure that you got the help you needed.

For your information, here are a few FAQ entries that might interest you :

        https://www.experts-exchange.com/help.jsp#hi403
Technically what you can assume is that
A pointer to a
structure object, suitably converted, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides), and vice versa.
But
There may be unnamed
padding within a structure object, but not at its beginning.
the standard header <stddef.h>.
defines
offsetof(type, member-designator)
which expands to an integer constant expression that has type size_t, the value of
which is the offset in bytes, to the structure member (designated by member-designator),
from the beginning of its structure (designated by type). The type and member designator
shall be such that given
static type t;
then the expression &(t.member-designator) evaluates to an address constant. (If the
specified member is a bit-field, the behavior is undefined.)