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

有帮助吗?

解决方案

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.

其他提示

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.

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.

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.

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top