前言
今天又听了一遍结构体内存对齐规则,明白了
按照结构体内存规则来计算, 再遇到结构体套结构体或结构体套数组的情况, 也能计算清楚。
试验
// hw.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stddef.h>
struct tagTest {
char c;
int i;
short w;
double dbl;
char c1;
};
/**
结构成员的对齐开始地址由结构成员size和默认对齐值中的最小者决定
如果结构成员是数组,数组的对齐开始地址由数组元素的size和默认对齐值中的最小者决定
一个结构成员的开始地址在上一个结构成员末尾的偏移地址开始计算
e.g.
假设默认对齐值是8
tagTest.c 偏移开始地址由上一个结构成员末尾地址(就是偏移0)开始计算, 对齐值为1(sizeof(char) = 1, 默认对齐值 = 8, 两者最小值为1), 0 % 1 = 0, 偏移地址 就是0
tagTest.i 偏移开始地址由上一个结构成员末尾地址(是偏移1)开始计算, 对齐值为4(sizeof(int) = 4, 默认对齐值 = 8, 两者最小值为4), 1 % 4 != 0, 偏移地址要推到4
tagTest.w 偏移开始地址由上一个结构成员末尾地址(是偏移8)开始计算, 对齐值为2(sizeof(short) = 2, 默认对齐值 = 8, 两者最小值为2), 8 % 2 == 0, 偏移地址 就是8
tagTest.dbl 偏移开始地址由上一个结构成员末尾地址(是偏移10)开始计算, 对齐值为8(sizeof(double) = 8, 默认对齐值 = 8, 两者最小值为8), 10 % 8 != 0, 偏移地址要推到16
tagTest.c1 偏移开始地址由上一个结构成员末尾地址(是偏移24)开始计算, 对齐值为1(sizeof(char) = 1, 默认对齐值 = 8, 两者最小值为1), 24 % 1 == 0, 偏移地址 就是24
结构的size由结构成员size最大者和默认对齐值中的最大者决定
e.g.
理论size = 24 + 1 = 25,
内存对齐值 = 结构的size由结构成员size最大者(8 => double)和默认对齐值(8)中的最大者(8)决定 = 8
实际size = 25 推到 32, 才能被内存对齐值整除
所以tagTest的实际size = 32
用offsetof 和 sizeof 对结构成员和结构size进行测量,可以验证内存对齐的规则
*/
int main(int argc, char* argv[])
{
printf("tag size = %d\r\n\r\n", sizeof(tagTest));
printf("offsetof(tagTest,c) = %d\r\n", offsetof(tagTest,c));
printf("char size = %d\r\n\r\n", sizeof(char));
printf("offsetof(tagTest,i) = %d\r\n", offsetof(tagTest,i));
printf("int size = %d\r\n\r\n", sizeof(int));
printf("offsetof(tagTest,w) = %d\r\n", offsetof(tagTest,w));
printf("short size = %d\r\n\r\n", sizeof(short));
printf("offsetof(tagTest,dbl) = %d\r\n", offsetof(tagTest,dbl));
printf("double size = %d\r\n\r\n", sizeof(double));
printf("offsetof(tagTest,c1) = %d\r\n", offsetof(tagTest,c1));
printf("char size = %d\r\n\r\n", sizeof(char));
/** run result
tag size = 32
offsetof(tagTest,c) = 0
char size = 1
offsetof(tagTest,i) = 4
int size = 4
offsetof(tagTest,w) = 8
short size = 2
offsetof(tagTest,dbl) = 16
double size = 8
offsetof(tagTest,c1) = 24
char size = 1
请按任意键继续. . .
*/
system("pause");
return 0;
}