c语言的内存对齐

253 阅读2分钟

为什么内存对齐

就是内存的对齐方式,为什么要求内存对齐呢,这是cpu的要求,在某些基于RISC(精简指令集计算机)的CPU,如Sparc powerpc等,对内存中的基本数据类型的变量采用高字节在低地址,低字节在高地址的存储 方式 ,在这种自然的存储格式中,要求变量在内存中的位置 必须自然对齐,否则cpu会报告异常。

intel的cpu没有这方面的要求,可以根据情况进行设置,arm的应该也可以,实际上我在arm上也是这样用的,对内存对齐进行自己的设置。

从上面种种消息可以基本推出:

1、字节对齐,可以提高内存查找效率

2、字节对齐的坏处就是:占用内存过多

因此,平衡两点,具体问题具体分析 所谓自然对齐,就是基本数据类型的变量不能简单的存储于内存的任意位置,它们的起始地址必须能够被它们的大小整除。

内存对齐的两种方式

有两种方法: 一是gcc的方式,如下:

 1 #include<stdio.h>
  2 struct unpacked_str{
  3 char c;
  4 int x;
  5 };
  6 struct packed_str{
  7 char c;
  8 int x;
  9 }__attribute__((packed));
 10 
 11 int main()
 12 {   
 13     printf("size of char=%lu\n",sizeof(char));
 14     printf("size of int=%lu\n",sizeof(int));
 15     printf("size of unpacked_str=%lu\n",sizeof(struct unpacked_str));
 16     printf("size of packed_str=%lu\n",sizeof(struct packed_str));
 17 }
~     
root@mkx:~/learn/packed# gcc packed.c -o packed
root@mkx:~/learn/packed# ./packed
size of char=1
size of int=4
size of unpacked_str=8
size of packed_str=5
root@mkx:~/learn/packed# 

别一种编译指令方式:

 1 #include<stdio.h>
  2 struct unpacked_str{
  3 char c;
  4 int x;
  5 };
  6 #pragma pack(push, 1)
  7 struct packed_str{
  8 char c;
  9 int x;
 10 };
 11 #pragma pack(pop)
 12 
 13 int main()
 14 {   
 15     printf("size of char=%lu\n",sizeof(char));
 16     printf("size of int=%lu\n",sizeof(int));
 17     printf("size of unpacked_str=%lu\n",sizeof(struct unpacked_str));
 18     printf("size of packed_str=%lu\n",sizeof(struct packed_str));
 19 }
root@mkx:~/learn/packed# ./packed2
size of char=1
size of int=4
size of unpacked_str=8
size of packed_str=5
root@mkx:~/learn/packed# 

内存对齐的内存映像

上面两种方式,效果是一样的,其内存映射如下:

image.png 通过上面可知,指定1为内存对齐方式,非常的节省内存,可以说一点内存都没有浪费,如果是默认,默认内存对齐是4,4的话,就浪费了3个字节的空间,

这还是小结构体,如果是大结构体,再加上数组的形式,那为了内存对齐,而占用的内存,还是非常大的。 对于嵌入式开发来说,这个还是特别注意的。