社区
C++ 语言
帖子详情
如何计算结构体的内存大小
weiyf2008
2006-11-10 10:36:02
一个结构体,比如说下面的两个
struct a{int i; int j[10]; double k; float l; char w[5];};
struct b{double q; char e[4]; char *p; int r;};
象这样的计算怎么算?不用sizeof运算符
...全文
432
6
打赏
收藏
如何计算结构体的内存大小
一个结构体,比如说下面的两个 struct a{int i; int j[10]; double k; float l; char w[5];}; struct b{double q; char e[4]; char *p; int r;}; 象这样的计算怎么算?不用sizeof运算符
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
6 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
myfriend023
2006-11-10
打赏
举报
回复
用#pragma pack(n)时 系统取的是自己现在设置的和原编译器已经设置的两个的最小值
即如果设置的n比原来的编译器的小则设置生效 如果大则不生效 继续使用原来的对齐系数
我啃
2006-11-10
打赏
举报
回复
还是再转一篇简单的文给你看看吧
本来,一般是不自己计算sizeof的,知道内存对齐会对sizeof有影响,所以从来不手算,而是代码里写上sizeof。今天又看到http://blog.vckbase.com/smileonce/archive/2005/08/08/10658.html,翻来了http://blog.vckbase.com/billdavid/archive/2004/06/23/509.html ,自己想想还是也记录一下,万一以后自己真的也要计算sizeof,忘了,还能有个提示,也给不是很明白的朋友一个参考。
struct sample1
{
char a; /// sizeof(char) = 1
double b; /// sizeof(double) = 8
};
///default( 缺省#pragam pack(8) ——VC6和VC71,其它编译器,个人未知 )
///1+8 = 9 —> 16( 8 < 9 < 16 )
#pragma pack( 4 )
///1+8 = 9 —> 12( 8 < 9 < 12 )
#pragma pack( 2 )
///1+8 = 9 —> 10( 8 < 9 < 10 )
#pragma pack( 1 )
///1+8 = 9 —> 9
#pragma pack( 16 )
///1+8 = 9 —> 16( 16—>8 ---- 8 < 9 < 16 )
struct sample2
{
char a; ///1
int b; ///4
};
#pragma pack( 8 )
/// 1 + 4 = 5 —> 8( 8 —> 4 )
#pragma pack( 16 )
/// 1 + 4 = 5 —> 8( 16 —> 4 )
说明:#pragma pack告诉编译器进行内存边界对齐,一般都是采用编译器的设置对整个项目采用同一对齐方案,而且通常为缺省8字节对齐。
今天又看到以前测试的一段代码,突然不明白了起来,又稍写了几个测试。
struct sample3
{
char a; ///1
int b; ///4
char c; ///1
};
///default ///12
#pragma pack( 4 ) ///12
#pragma pack( 2 ) ///08
#pragma pack( 1 ) ///06
#pragma pack( 16 ) ///12
原来,其实编译器,根据对齐指示的对齐字节和最大成员的字节,对每个成员进行了对齐:编译器会取对齐指示和最大成员字节中较小的一个用于补齐其它成员。那么,上面的sample1/2/3也就都在情理之中了。为了证实这点,我们还再看一个例子:
struct sample4
{
char a; ///1
int b; ///4
double c; ///8
char d; ///1
};
///default: ///8+8+8+8 = 32
#pragma pack( 4 ) ///4+4+8+4 = 20
#pragma pack( 2 ) ///2+4+8+2 = 16
#pragma pack( 1 ) ///1+4+8+1 = 14
#pragma pack( 16 ) ///8+8+8+8 = 32
而实际上,编译器给出的值是:24、20、16、14、24
那么说明我错了。注意一下,我发现char a,int b加起来也才5<8,难到编译器进行了联合对齐?
struct sample5
{
char a; ///1
double c; ///8
int b; ///4
char d; ///1
};
编译器给出结果:24、20、16、14、24
这用联合对齐的解释正好符合,我又试验了不同的数据,发现这个结论并不太准确确。于是,我输出了每一个对象成员地址进行分析。由于试验数据量很大,这里就不列出了。
最后得到了以下结论:
1. 成员的对齐是按声明顺序进行的;
2. 对齐值由编译指示和最大成员两者较小的值决定;
3. 未对齐到对齐值的成员一起形成块对齐(联合对齐);
4. 上一个(下一个)对齐采用自己较大则不变,自己较小则填充自己对齐到上一个(下一个)大小;
5. 每成员对齐:如果前面已对齐到对齐值,下一个对齐自己。如果前面未对齐到对齐值,如果加上下一个成员不大于对齐值,下一个对齐自己,否则填充自己块对齐到对齐值。
6. 最后还未对齐到对齐值的,填充空间块对齐到对齐值。
从这些结论,可以得到:
1. 以上的对齐原则其实是尽量整齐排列、尽量节省内存。
2. 声明成员应该尽量避免不同类型错杂开来,最好采用从小到大或者从大到小的顺序(错开后,会因为上对齐和下对齐而增加填充开销)。
3. 编译器缺省采用8字节对齐主要是因为最大基本类型为8自己(以前自己不明白,在论坛提过问,后来,以为是SSE指令的原因)。
4. 手算sizeof是没有必要的,负责的(可以先对齐出对齐块,用块数乘对齐值)。
////////////////////////////////////////////////////////////////////////////////////////////////////////
在最近的项目中,我们涉及到了“内存对齐”技术。对于大部分程序员来说,“内存对齐”对他们来说都应该是“透明的”。“内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。
一、内存对齐的原因
大部分的参考资料都是如是说的:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
二、对齐规则
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
我啃
2006-11-10
打赏
举报
回复
手动计算,根据编译器特性,一般sizeof(int)=4
char=1
long=4
short=2
double=8
数组算多个,同时要求注意内存对齐的问题,这个CSDN里已经不知道又多少文了
shootingsyh
2006-11-10
打赏
举报
回复
除非写底层代码,否则不要pack,移植性上有问题
lsm_1982
2006-11-10
打赏
举报
回复
包含位域的话,不可以跨过该类型的大小。
不同的类型,必须考虑对齐,该类型的倍数的内存出开始存放。
最后与最大的类型的对齐
taodm
2006-11-10
打赏
举报
回复
由于受对齐影响,楼主还是老老实实坚持用sizeof吧。
这个问题恐怕不是2、3天你能搞得很精通的。
结构体
内存对其
计算
结构体
大小
结构体
内存对其
计算
结构体
大小,大神总结,很有用,
结构体
内存对其
计算
结构体
大小,
结构体
内存对其
计算
结构体
大小
结构体
内存对其
计算
结构体
大小
结构体
所占内存空间的
计算
详细的介绍了如何
计算
结构体
在内存中的分布,从而达到
计算
结构体
类型所占
内存大小
的目的。
《C深度解析》第7、8章
结构体
/共用体/枚举,杂项(自动类型转换、大小端序等)
第7章:1.
结构体
结构体
定义、访问、传参,
结构体
对齐(offsetof宏、contaner_of宏),
结构体
内嵌函数指针,程序分层,模块化等。2. 共用体共用体与
结构体
的异同、共用体的作用、共用体举例3. 枚举第8章:自动类型转换、大小端序、typedef、编译器优化、extern C、程序调试、变参函数、dowhile(0)、内嵌汇编、调试版与发行版、断言
GoLang之内存对齐、
计算
结构体
内存大小
GoLang之内存对齐、
计算
结构体
内存大小
学懂如何
计算
结构体
内存大小
结构体
内存对齐方式需要同时满足数据内存对齐与
结构体
整体内存对齐两个限制要求。数据内存对齐数 = min(数据所占字节数,默认对齐数)。默认对齐数是编译器所规定的。在32位机器下是4字节,64位机器下是8字节。各常用类型数据对齐数如下:
结构体
整体内存对齐数 = min(最大数据类型字节,默认对齐数)最大数据类型字节就是这个
结构体
中所有数据类型中所占字节最大的类型。默认对齐数与文一致,32位下是4字节、64位下是8字节。
C++ 语言
64,647
社区成员
250,476
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章