How do I determine the memory layout of a structur

2019-05-16 01:29发布

问题:

Suppose I have the following structure (in C):

struct my_struct {
  int foo;
  float bar;
  char *baz;
};

If I now have a variable, say

struct my_struct a_struct;

How can I find out how the fields of that structure are going to be laid out in memory? In other words, I need to know what the address of a_struct.foo, of a_struct.bar and a_struct.baz are going to be. And I cannot do that programatically, because I am actually cross-compiling to another platform.

CLARIFICATION

Thanks the answers so far, but I cannot do this programatically (i.e. with the offsetof macro, or with a small test program) because I am cross-compiling and I need to know how the fields are going to be aligned on the target platform. I know this is implementation-dependent, that's the whole point of my question. I am using GCC to compile, targeting an ARM architecture.

What I need in the end is to be able to dump the memory from the target platform and parse it with other tools, such as Python's struct library. But for that I need to know how the fields were laid out.

回答1:

In general, this is implementation specific. It depends on things like the compiler, compiler settings, the platform you are compiling on, word-size, etc. Here's a previous SO thread on the topic: C struct memory layout?

If you are cross-compiling, I'd imagine the specific layout will be different depending on which platform you compile for. I'd consult references for your compiler and platform.



回答2:

There's a program called pahole (Poke-A-Hole) in the dwarves package that will produce a report showing the structures of your program along with markers showing where and how large padding is.



回答3:

I think you have two options.

The first one is to use __attribute__((packed)) after the struct declaration. This will ensure that each member will be allocated exactly the amount of memory that its type requires.

The other one is to examine your structure and use the alignment rules (n-byte basic type variable has to be n-byte aligned) to figure out the layout.

In your example, in either case each member variable will take 4 bytes and the structure will occupe 12 bytes in memory.



回答4:

One hacky way to see the memory view of what's inside it would be to cast a struct pointer to a char pointer, then print out all the chars, something like:

struct my_struct s;
s.foo = MAX_INT;
s.bar = 1.0;
s.baz = "hello";

for (int i = 0; i < sizeof(s); i++) {
  char *c = ((char*)&s) + i;
  printf("byte %d: 0x%02x\n", i, *c);
}

That doesn't explicitly show you the boundaries, you'd have to infer that from the dump.

Comments made by others about packing still apply; you'll also want to use explicitly sized types like uint32 instead of unsigned int