2
struct s
{
  int a;
  float b;
  int c;
}

How is this structure members stored in memory location? My understanding is that when a structure variable is allocated then memory for the structure members will also be allocated. If 1000 is the starting address then a will be at 1000, b will be 1004, and c will be 1008.

Integers and float will have different address spaces in the memory. How is a float and an integer declared inside the struct represented in memory? Please help me to understand.

Angus
  • 12,133
  • 29
  • 96
  • 151
  • 2
    A float and an integer inside a structure are represented the same as a float and an integer outside a structure. Also, there is no possiblity of allocating memory for a structure and not allocating the memory for its members. (If you had pointer members, then there'd be no space allocated for what the pointers point to, but that's a different issue.) – Jonathan Leffler Aug 29 '11 at 17:25
  • It's an implementation detail. Why do you want to know? If this is really homework, tell your professor/teacher that he needs to specify a platform and a compiler. ;p – Jonathan Grynspan Aug 29 '11 at 17:30

4 Answers4

3

Assuming sizeof(int) == sizeof(float) == 4 and that the compiler doesn't decide to put some padding in, your answer is correct. I don't know what "Integers and float will have different address spaces in the memory" means, so I'm not sure I can answer your final question.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • 2
    Note that there are platforms in practice where `sizeof(int) != sizeof(float)` – bdonlan Aug 29 '11 at 17:31
  • It is usually (98% of the time) 4 bytes (32 bits). – ahmet alp balkan Aug 29 '11 at 17:37
  • 1
    @ahmet, if we're measuring by the sheer number of deployments, the number of cases where `sizeof(int) == 4` is actually a _minority_. It's only in the desktop PC and server market where this is a majority (and given the number of embedded processors on modern PCs, this may not even be the case in that market, either) – bdonlan Aug 29 '11 at 17:38
  • I don't know about minority, but there are certainly lots that go both ways. The number of ARMs out there where this relationship is true is extremely large these days too... – Carl Norum Aug 29 '11 at 17:40
  • 1
    @bdonlan: That why he said "assuming". You have to pick SOME value when you're giving an example. In any case, while I have used platforms where sizeof(int)=2, that was a long time ago. What are you thinking of as the majority counter-example? Cell phones or something? – Jay Aug 29 '11 at 17:42
  • 1
    @Jay: There are 16-bit (or smaller) microcontrollers literally all over the place. Cell phones is one, hoovers, cars, toasters are others. – Oliver Charlesworth Aug 29 '11 at 17:51
  • Don't forget digital watches, industrial robots, microwaves, power meters, RFID tags, etc etc... – bdonlan Aug 29 '11 at 17:58
2

How is this structure members stored in memory location? My understanding is that when a structure variable is allocated then memory for the structure members will also be allocated. If 1000 is the starting address then a will be 1000 b will be 1004.will c be 1008.

Since the size of int and even float is platform specific as is how structures are packed/stored/aligned/retrieved in memory, there is no platform neutral answer to your question.

If it matters to you how structs are stored in memory, you'll have to look into some compiler-specific ways to ensure structs are properly packed and aligned. For gcc see here for how to use __attribute__ to control packing and alignment. For MSVC see here for how to use pragma pack.

Of course HERE BE DRAGONS:

You're venturing into the platform-specific way of how data is stored in memory, yarr there be many opportunities for bugs if you're taking this hunk of memory and sending it off to another device. To prevent bugs (and there will be bugs) keep in mind:

  • Endianess.
  • If you're casting to a pointer of another type (ie type-punning or aliasing) beware that C99 won't support pointer aliasing. See the strict aliasing rule.
Community
  • 1
  • 1
Doug T.
  • 64,223
  • 27
  • 138
  • 202
2

It's not really meaningful to say that the members of a struct are allocated at the same time as a struct. A struct is simply the collection of its members. There is no additional data to a struct that you could meaningfully say that "the struct was allocated but not the members".

Exactly how memory is allocated depends on the platform and the compiler. If, say, an int and a float are both 4 bytes -- which I think is typical -- then this struct would consist of 12 bytes, the three fields one after the other.

Compilers sometimes put all the fields in a struct on 4-byte boundaries, or some other boundary. So if you had a struct made up of a char, a float, and an int, you'd probably get 1 byte for the char, 3 filler bytes, then 4 for the float and 4 for the int.

Integers and floats DON'T have different address spaces in memory, at least not on any system I've ever used. They're freely mixed together. The processor may have separate int and float registers, but that's a whole different thing.

Jay
  • 26,876
  • 10
  • 61
  • 112
0

You can use offsetof macro to get structure member offset. Add this offset to structure address to get address of member.

typedef struct s {
  int a;
  float b;
  int c;
} s_t;

s_t var;

printf("var.c addresss=%p\n",((const uint8_t*)&var)+offsetof(s_t,c));
vromanov
  • 881
  • 6
  • 11
  • 2
    This won't work, as `var` is of type `s_t` and `offsetof` gives the offset in bytes, so you need to cast `&var` to `char*` (assuming 1-byte chars, or maybe better `size_t`) – Christian Rau Aug 29 '11 at 17:37
  • You have to convert the `&var` to a `void *` (or `char *`) before adding the offset is accurate. As it stands, `&var+offsetof(s_t,c)` yields undefined behaviour as it accesses the address of `8 * sizeof(s_t)` 'beyond' `&var` (approximately `&var[8]`) assuming 4-bye `int` and `float`. This is a very different address from the address of `c` in `var`. – Jonathan Leffler Aug 29 '11 at 17:42