首页 / C语言 / C语言结构体之内存对齐
C语言结构体之内存对齐
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C语言结构体之内存对齐,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3228字,纯文字阅读大概需要5分钟。
内容图文
C语言结构体之内存对齐
1、什么是内存对齐
首先看一个例子,下面有一个结构体:
struct structTest1 { char c1; short s; char c2; int i; };
假设这个结构体成员在内存中是紧凑排列的,那么c1的存储地址就是0,s的存储地址是1-2,c2的存储地址是3,i的存储地址是4-7,c1的地址是0000000000000000,s的地址是0000000000000001,c2的地址是0000000000000003,i的地址是0000000000000004,整个结构体所占内存是8。但是写一个程序输出一下,则会得到不同的结果。
#include <stdio.h> struct structTest1 { char c1; short s; char c2; int i; }; int main() { struct structTest1 s1; printf("sizeof(s1): %d\n", sizeof(s1)); printf("c1:%p\ns :%p\nc2:%p\ni :%p\n",\ (unsigned int)(void*)&s1.c1 - (unsigned int)(void*)&s1,\ (unsigned int)(void*)&s1.s - (unsigned int)(void*)&s1,\ (unsigned int)(void*)&s1.c2 - (unsigned int)(void*)&s1,\ (unsigned int)(void*)&s1.i - (unsigned int)(void*)&s1); return 0; }
程序的输出结果与我们预测的结果不一致,这就是因为内存对齐导致的。
内存对齐就是,按照成员的声明顺序,依次安排内存,其偏移量为最大成员大小的整数倍,最后结构体的大小为最大成员的整数倍。
2、为什么会有内存对齐
因为访问未对齐的内存,处理器需要做两次内存访问,然而对齐的内存访问仅需要一次访问。缺省情况下,编译器默认将结构、栈中的成员数据进行内存对齐。编译器将未对齐的成员往后移,将每一个成员都对齐到自然边界上,从而也导致了整个结构体的尺寸变大。尽管会牺牲一点空间(成员间有部分内存空闲),但提高了性能。
3、如何避免内存对齐的影响
一个小技巧就是将上面的结构体写成下面的形式:
struct structTest1 { char c1; short s; char c2; int i; };这样一来,每个成员都对齐在其自然边界上,从而避免了编译器自动对齐。
#include <stdio.h> struct structTest1 { char c1; char c2; short s; int i; }; int main() { struct structTest1 s1; printf("sizeof(s1): %d\n", sizeof(s1)); printf("c1:%p\nc2:%p\ns :%p\ni :%p\n",\ (unsigned int)(void*)&s1.c1 - (unsigned int)(void*)&s1,\ (unsigned int)(void*)&s1.c2 - (unsigned int)(void*)&s1,\ (unsigned int)(void*)&s1.s - (unsigned int)(void*)&s1,\ (unsigned int)(void*)&s1.i - (unsigned int)(void*)&s1); return 0; }
除此之外我们还可以利用#pragma pack()来改变编译器的默认对齐方式 使用指令#pragma pack (n),编译器将按照 n 个字节对齐。 使用指令#pragma pack (),编译器将取消自定义字节对齐方式。 在#pragma pack (n)和#pragma pack ()之间的代码按 n 个字节对齐。 当n=1时:
#include <stdio.h> #pragma pack(1) struct TestStruct1 { char a; long b; }; struct TestStruct2 { char c; struct TestStruct1 d; long long e; }; #pragma pack() int main() { printf("sizef(TestStruct2): %d\n", sizeof(struct TestStruct2)); return 0; }
当n=2时
#include <stdio.h> #pragma pack(2) struct TestStruct1 { char a; long b; }; struct TestStruct2 { char c; struct TestStruct1 d; long long e; }; #pragma pack() int main() { printf("sizef(TestStruct2): %d\n", sizeof(struct TestStruct2)); return 0; }
当n=4时
#include <stdio.h> #pragma pack(4) struct TestStruct1 { char a; long b; }; struct TestStruct2 { char c; struct TestStruct1 d; long long e; }; #pragma pack() int main() { printf("sizef(TestStruct2): %d\n", sizeof(struct TestStruct2)); return 0; }
当n=8时
#include <stdio.h> #pragma pack(8) struct TestStruct1 { char a; long b; }; struct TestStruct2 { char c; struct TestStruct1 d; long long e; }; #pragma pack() int main() { printf("sizef(TestStruct2): %d\n", sizeof(struct TestStruct2)); return 0; }
?
内容总结
以上是互联网集市为您收集整理的C语言结构体之内存对齐全部内容,希望文章能够帮你解决C语言结构体之内存对齐所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。