22

While attempting to create a memory manager for future C programs, I've come across this question:

"when structs are allocated, are their member fields stored in the order specified?"

For instance, consider the following struct.

typedef struct {
    int field1;
    int field2;
    char field3;
} SomeType;

When allocated, will the memory addresses of the fields be in the order field1, field2, field3? Or is this not guaranteed?

Community
  • 1
  • 1
  • 1
    You should have searched with the exact same question string first. Here's what I found: http://stackoverflow.com/questions/2748995/c-struct-memory-layout – Hariprasad Dec 23 '13 at 04:57

3 Answers3

42

Short answer: they are allocated with the order as they declared in the struct.


Example:

#include <stdio.h>
#include <string.h>

struct student 
{
    int id1;
    int id2;
    char a;
    char b;
    float percentage;
};

int main() 
{
    int i;
    struct student record1 = {1, 2, 'A', 'B', 90.5};

    printf("size of structure in bytes : %d\n", 
        sizeof(record1));

    printf("\nAddress of id1        = %u", &record1.id1 );
    printf("\nAddress of id2        = %u", &record1.id2 );
    printf("\nAddress of a          = %u", &record1.a );
    printf("\nAddress of b          = %u", &record1.b );
    printf("\nAddress of percentage = %u",&record1.percentage);

    return 0;
}

Output:

size of structure in bytes : 16 
Address of id1 = 675376768
Address of id2 = 675376772
Address of a = 675376776
Address of b = 675376777
Address of percentage = 675376780

The pictorial representation of above structure memory allocation is given below. This diagram will help you to understand the memory allocation concept in C very easily.

enter image description here


Further reading: check out here (also the source for the above example) for C – Structure Padding and Structure dynamic memory allocation in C.

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
7

You are guaranteed that field3 comes after field2, which comes after field1, and that field1 is at the start of the memory (i.e. there's no padding before field1). However, they may be padding in between the other members (and even after field3). In short, the order in which they are declared is the order in which they are laid out in memory, though exact alignment and padding is implementation defined (but there won't be any padding before the first member).

Cornstalks
  • 37,137
  • 18
  • 79
  • 144
  • 1
    To be precise, it's guaranteed that `SomeType x; ((void*) &x) == ((void*) &x.field1)`. – orlp Dec 23 '13 at 04:58
  • Why there would be padding before a member! – rullof Dec 23 '13 at 05:26
  • @rullof: Padding before a member is the same as padding after the previous member. If there's padding between `field1` and `field2`, you can say that padding is after `field1`, or you can alternatively say there is padding before `field2`. Neither statement is incorrect; it just depends on perspective. But if I misinterpreted your question, and you were instead wondering why there might be any padding at all, then the answer is [all about aligning things in memory with the processors native alignment requirements](http://en.wikipedia.org/wiki/Data_structure_alignment). – Cornstalks Dec 23 '13 at 05:46
  • I mean why should be a padding between members. What's the purpose of it? – rullof Dec 23 '13 at 05:48
  • 1
    @rullof: Oops; well in that case I amended the previous comment. But to expand a bit more, x86 *requires* that `int` is aligned on 4-byte boundaries (if `int` is 4 bytes), while `char` has no such restriction (it as a 1-byte alignment, so can be anywhere in memory). If you have an `int` after a `char`, 3 bytes of padding are needed to make sure the `int` lines up on a memory address that's divisible by 4. – Cornstalks Dec 23 '13 at 05:51
  • @Cornstalks I got it tanks! – rullof Dec 23 '13 at 05:54
0
  1. Members are located one by one;
  2. Every member's start location shoule be divide exactly by its length:

For example:

typedef struct {
   char field1;
   int field2;
   double field3;
} SomeType;

The struct's first location is x:

field1's length is 1(byte), filed2 is 4, field3 is 8

so field1 is at x+0, field2 is at x+4~x+7, field3 is at x+8~x+15, and x+1~x+3 is padded to make field2 at right place.

And the whole struct's length should be divide exactly by its largest member; if not, padding some bytes to the end.

Nagarjun
  • 6,557
  • 5
  • 33
  • 51
SliceSort
  • 357
  • 3
  • 5