C/C++数据对齐

简介:

为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认对齐值是8,各数据类型所占字节数分别为

char占一个字节

int占四个字节

double占八个字节。

两个例子

请问下面的结构体大小是多少?


  
  
struct Test
{
char c ;
int i ;
};

这个呢?


  
  
struct Test1
{
int i ;
double d ;
char c ;
};

在公布答案之前先看一下对齐的规则。

对齐规则

一般来说,结构体的对齐规则是先按数据类型自身进行对齐,然后再按整个结构体进行对齐,对齐值必须是2的幂,比如1,2, 4, 8, 16。如果一个类型按n字节对齐,那么该类型的变量起始地址必须是n的倍数。比如int按四字节对齐,那么int类型的变量起始地址一定是4的倍数,比如0x0012ff60,0x0012ff48等。

 

数据自身的对齐

数据自身的对齐值通常就是数据类型所占的空间大小,比如int类型占四个字节,那么它的对齐值就是4

整个结构体的对齐

整个结构体的对齐值一般是结构体中最大数据类型所占的空间,比如下面这个结构体的对齐值就是8,因为double类型占8个字节。


  
  
struct Test2
{
int i ;
double d ;
};

例子答案

有了上面的基础,再回过头去看看一开始的两个例子

先看结构体Test

1 c是char类型,按1个字节对齐

2 i是int类型,按四个字节对齐,所以在c和i之间实际上空了三个字节。

整个结构体一共是1 + 3(补齐)+ 4 = 8字节。

再看Test1

i是int类型,按4字节对齐

d是double类型,按8字节对齐,所以i和d之间空了4字节

c是char类型,按1字节对齐。

所以整个结构体是 4(i) + 4(补齐)+ 8(d) + 1(c) =  17字节,注意!还没完,整个结构体还没有对齐,因为结构体中空间最大的类型是double,所以整个结构体按8字节对齐,那么最终结果就是17 + 7(补齐) = 24字节。

书写结构体的建议

我们对Test1做一点改动


  
  
struct Test1
{
char c ;
int i ;
double d ;
};

这时Test1的大小就变成了16,而不是24了,节省了8个字节!可见结构体中成员的书写顺序对结构体大小的影响还是很大的,一个好的建议是,按照数据类型由小到大的顺序进行书写。

如何查看结构体的对齐值

使用预处理命令

#pragma pack(show)

该命令来查看当前的对齐值,但是要注意的是,结果是以warning的形式输出的,所以要在VS的警告窗口中才看得见,如下

warning C4810: value of pragma pack(show) == 8   

使用Visual Studio选项(以Visual Studio 2008为例)

Projects-Properties-Configuration Properties-C/C++-Code generation-Struct Member Alignment, 如果没有修改过,则默认值是Default,即8字节对齐。

如何修改结构体的对齐值

使用预处理指令

#pragma pack(num)

num是结构体的对齐值,比如下面的例子按四个字节对齐。

#pragma pack(4)

使用Visual Studio选项(以Visual Studio 2008为例)

Projects-Properties-Configuration Properties-C/C++-Code generation

参考

http://msdn.microsoft.com/en-us/library/ms253949.aspx

http://msdn.microsoft.com/en-us/library/ms253935.aspx


本文转自zdd博客园博客,原文链接:http://www.cnblogs.com/graphics/archive/2010/08/12/1797953.html,如需转载请自行联系原作者

相关文章
|
5月前
|
存储 Serverless 数据安全/隐私保护
C++ 类的成员函数和数据成员的技术性探讨
C++ 类的成员函数和数据成员的技术性探讨
60 0
|
2月前
|
存储 C++
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
|
2月前
|
存储 算法 C++
C++ STL应用宝典:高效处理数据的艺术与实战技巧大揭秘!
【8月更文挑战第22天】C++ STL(标准模板库)是一组高效的数据结构与算法集合,极大提升编程效率与代码可读性。它包括容器、迭代器、算法等组件。例如,统计文本中单词频率可用`std::map`和`std::ifstream`实现;对数据排序及找极值则可通过`std::vector`结合`std::sort`、`std::min/max_element`完成;而快速查找字符串则适合使用`std::set`配合其内置的`find`方法。这些示例展示了STL的强大功能,有助于编写简洁高效的代码。
40 2
|
2月前
|
编译器 C++
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
virtual类的使用方法问题之C++类中的非静态数据成员是进行内存对齐的如何解决
|
2月前
|
存储 数据挖掘 C语言
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
【C/C++】C/C++车辆交通违章管理系统(源码+数据文件)【独一无二】
|
2月前
|
存储 安全 数据处理
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
【C++】C++ 超市会员卡管理系统(面向对象)(源码+数据)【独一无二】
|
3月前
|
存储 C++ 容器
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
52 5
|
3月前
|
设计模式 监控 Go
开发与运维C++问题之C++部分原有的数据发送能力如何解决
开发与运维C++问题之C++部分原有的数据发送能力如何解决
25 1
|
3月前
|
存储 数据格式 运维
开发与运维C++问题之更改数据模型为通用数据结构如何解决
开发与运维C++问题之更改数据模型为通用数据结构如何解决
26 1
|
2月前
|
存储 算法 C++
【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】
【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】