0

i have a query on following C programme

code:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct a
    {
        char arr[10];
        int i;

        float b;
    }v[2];

    printf("\n %d   %d  %d  \n",v[0].arr, &v[0].i, &v[0].b);
    printf("\n %d   %d  %d  \n",v[1].arr, &v[1].i, &v[1].b);


    printf("\nHello world!\n");
    return 0;
}

Output:

 2686712   2686724  2686728

 2686732   2686744  2686748

 Hello world!

Question: v[0].arr == 2686712 and arr[10] that has size 10 bytes &v[0].i <<<< this address should start immediately after the array .. since array is of 10 bytes .. the address of &v[0].i should start from 2686712+10 i.e 2686722 why is &v[0].i == 2686724 and not 2686722

2
  • Memory is aligned so that the CPU can read it in blocks. (Assuming this is a 32-bit machine) Despite only 10 byte are being in use, 12 bytes alignment is preferred so that the next value (which happens to be a int) will be read as an int more quickly (without any arithmetics) and a (4's multiple) bytes groups. Commented Mar 24, 2014 at 17:05
  • possible duplicate of What exactly is an 'aligned pointer'? Commented Mar 24, 2014 at 17:06

5 Answers 5

3

The compiler pads structure members to keep things aligned properly for each data type.

See this link for information on how structure padding actually works. There is a lot of very detailed information there. See also this link for alignment information specific to the intel processor for the various data types.

In essence, because you have a 10-byte char array followed by an int, the compiler has padded the char array with an extra 2 bytes so that the int will be aligned properly on a 4-byte boundary (that is, an address evenly divisible by 4).

It is as if you declared your structure like this:

struct a
{
    char arr[10];
    char _padding[2];
    int i;
    float b;
};

Out of habit, I usually allocate char arrays with sizes that are evenly divisible by 4. That way the compiler doesn't have to do it for me, and it makes it easier to visualize what the data structure looks like in memory.

Sign up to request clarification or add additional context in comments.

9 Comments

Windows align on byte boundaries for all data types.
@JackCColeman: I sure hope that's not true. That would cause a major performance problem, since the intel processor wants data to be naturally aligned... See software.intel.com/en-us/articles/… for more info.
from what I can tell, the C libs for windows define/allow LONG on byte boundaries. Just browsed the article, my response, is this is old-time technology, are processors really constrained this way? With up to three levels of cache word boundaries seem irrelevant??
@JackCColeman: Newer processors take less of a hit, but it still does matter to some extent - See lemire.me/blog/archives/2012/05/31/… where the author did some testing that still shows a 10% performance penalty even with recent processors (that was in 2012).
I would guess that the attitude is that the effort required to align on "correct" boundaries is so processor specific that it isn't worth the headaches at the software level, especially when shipping a product to many PCs (for example, what happens if the customer upgrades a CPU but nothing else?)
|
3

The compiler is allowed insert padding in between members of a struct or at the end but not at the beginning. From the draft C99 standard section 6.7.2.1 Structure and union specifiers paragraph 13 which says (emphasis mine):

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. 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. There may be unnamed padding within a structure object, but not at its beginning.

and paragraph 15:

There may be unnamed padding at the end of a structure or union.

by using %d format specifier for a pointer you are invoking undefined behavior you should be using %p.

Comments

2

First: You shouldn't use %d to print a pointer with printf but %p.

Second: Only the first element of a struct is guaruanteed to start at the adress of the structure. Any other member can have padding bytes inserted, depending on the compiler and architecture requirements.

Comments

1

Most compilers will pad your struct elements by default to the member size. Thus there will be two padding bytes after arr.

Use struct {...} __attribute__(packed); if you wish to have a fully packed struct.

2 Comments

Isn't __attribute__(packed) a gcc/g+++ specific construct?
@RSahu Yes, but most modern compilers either support it or have their own version though flags, pragmas or similar.
0

On your system 4-byte alignment happens.

and

"int" and "float" will take 4-byte "char" will 1-byte

1)in your question your structure you are wasting 2-byte because of sequence

struct a {

    char arr[10];
    int i;
    float b;

}v[2];

ANS::2)My solution is just change sequence of "char arr[10]", put it in last


struct a

{

     int i;

    float b;

    char arr[10];


}v[2];

Now if you will print address then it will print according your understanding...

3)Memory alignment can be changed as per your requirement which is provided by Compiler using "PRAGMA" search "PRAGMA" on google to use.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.