struct中的地址对齐

来源:互联网 发布:windows进程内存监控 编辑:程序博客网 时间:2024/06/10 04:35

下文在gcc编译器中测试通过,32位的RedHat9.0
struct结构体中每个数均按照地址对齐的方式排列
#include
typedef struct
{
    unsigned short a;
    unsigned long  b;
}S1;
typedef struct
{
    unsigned short a;
    unsigned long  b;
    unsigned char c[2];
}S2;
typedef struct
{
    unsigned short a;
    unsigned char c[2];
    unsigned long b;
}S3;

int main()
{
    S1 t1;
    S2 t2;
    S3 t3;
    int i;

    printf("sizeof(t1):%d/n",sizeof(t1));
    printf("sizeof(t2):%d/n",sizeof(t2));
    printf("sizeof(t3):%d/n",sizeof(t3));

    for(i=0;i        *(((unsigned char*)(&t1))+i)=i+1;
    }
    printf("t1.a:%x t1.b:%x/n",t1.a,t1.b);
    for(i=0;i        *(((unsigned char*)(&t2))+i)=i+1;
    }
    printf("t2.a:%x t2.b:%x t2.c[0]:%x t2.c[1]:%x/n",t2.a,t2.b,t2.c[0],t2.c[1]);

    for(i=0;i        *(((unsigned char*)(&t3))+i)=i+1;
    }
    printf("t3.a:%x t3.b:%x t3.c[0]:%x t3.c[1]:%x/n",t3.a,t3.b,t3.c[0],t3.c[1]);

    return 0;
}
上述程序的最终输出结果为:
sizeof(t1):8
sizeof(t2):12
sizeof(t3):8
t1.a:201 t1.b:8070605
t2.a:201 t2.b:8070605 t2.c[0]:9 t2.c[1]:a
t3.a:201 t3.b:8070605 t3.c[0]:3 t3.c[1]:4
由此可知结构体S1在内存中的排列顺是这样的:
1、最初2个字节幅值被unsigned shor a占用
2、接下来的2个字节是空闲的,不被程序利用
3、最后的4个字节被unsigned long占用
同理S2、S3也类似,每个变量均须满足地址对齐
ELF格式的文件头定义如下:
#define EI_NIDENT 16
typedef struct{
    unsigned char    e_ident[EI_NIDENT];
    Elf32_Half        e_type;
    Elf32_Half        e_machine;
    Elf32_Word        e_version;
    Elf32_Addr        e_entry;
    Elf32_Off        e_phoff;
    Elf32_Off        e_shoff;
    Elf32_Word        e_flags;
    Elf32_Half        e_ehsize;
    Elf32_Half        e_phentsize;
    Elf32_Half        e_phnum;
    Elf32_Half        e_shentsize;
    Elf32_Half        e_shnum;
    Elf32_Half        e_shstrndx;
}Elf32_Ehdr;
名称                 大小        对齐
Elf32_Addr       4            4
Elf32_Half        2            2
Elf32_Off         4            4
Elf32_Sword   4            4
Elf32_Word     4            4
unsigned char 1            1
这样排列Elf32_Ehdr内的变量可以保证结构体内没有空闲
按照对齐的方式排列各个变量可以确保结构体内没有空闲空间
如果把 EI_NIDENT 改成17
那么e_idnet数组后面有1个字节空闲,而e_machine变量后面则有2个字节空闲,为了保证地址对齐
因此如果EI_NIDENT一定要改成17的话,则把e_ident这个数组放在结构体的最后即可