c 字节对齐

概念:

结构体里会包括各种类型的成员,比如int char long等等,它们要占用的空间不同,系统为一个结构体开辟内存空间时,会有2种选择。

  • 第一种:节省空间的方案,以上面的列子来说的话,就是4(int) + 1(char) + 8(long) =13个字节;
  • 第二种:浪费空间的方案,以上面的列子来说的话,就是4(int) + 4(char) + 8(long) =16个字节;

其实,系统是用的第二种方案。

字节对齐的目的:

为了CPU只寻找地址一次,就能够把目标内存中的数据取出来。

现代计算机中内存空间都是按照byte划分的 ,如果是用第一种节省空间的方案,为了要取一个int或者long的成员的值,CPU寻址一次,可能只取出来一部分,所以需要再次寻址,这样就导致CPU的效率降低。为了提高CPU的效率,所以选择牺牲空间,但是节省了时间。

经验总结

声明结构体成员的时候,一定把占用空间最小的类型放在最前面,占用空间最大的放在最后面,这样就会节省内存空间。

程序验证

#include <stdio.h>

typedef struct A{
char a;
char b;
char c;
}A;
//#pragma pack(4) //如果把注释打开就是强制按4字节对齐,所以就是16
typedef struct B{//24
int a;//占用4字节 + 4 //往下看,下面的8字节,所以补4个字节
long b;//占用8字节
char c;//占用1字节+ 7 // 4+4+8+1=9,但9不是8的倍数,所以在最后的char c处加7个字节
}B;
typedef struct C{//16
char a;//1 + 3
int b;//4
long c;//8
}C;
struct D{//32
int a;//4 + 4 //往下看,下面的8字节,所以补4个字节
struct S1{//16
long b;//8
char c;//1 + 1 //往下看,下面的2字节,所以补1个字节
short d;//2 + 4 //8+2+2=12但不是8的倍数,所以在最后的short d处加4个字节
} aa;
int e;//4 + 4 //8+16+4=28但不是8的倍数,所以在最后的int e处加4个字节
}D;
struct E{//40
int a;//4 + 4
struct S2{//24
short d;//2 + 6 //往下看,下面的8字节,所以补6个字节
long b;//8
char c;//1 + 7 //8+8+1=17但不是8的倍数,所以在最后的char c处加7个字节
} aa;
int e;//4 + 4 ////8+24+4=36但不是8的倍数,所以在最后的int e处加4个字节
}E;
struct F{//72
int a;//4 + 4
struct {//56
short d[20];//40 //不管数组里多少个元素,只看数组的类型
long b;//8
char c;//1 + 7
} ;
int e;//4 + 4
}F; int main(){
printf("A size = %ld\n",sizeof(A));
printf("B size = %ld\n",sizeof(B));
printf("C size = %ld\n",sizeof(C));
printf("D size = %ld\n",sizeof(D));
printf("E size = %ld\n",sizeof(E));
printf("F size = %ld\n",sizeof(F));
B B1;
B1.a = 10;
B1.b = 12;
B1.c = 'A';
}

运行结果:

A size = 3
B size = 24
C size = 16
D size = 32
E size = 40
F size = 72

位域

变量可以按比特位进行定义,比如定义只占用1个比特位的char c:1;

只占用10个比特位的int i:10;

**定义的比特位不可以超过类型自身所占用的字节数 **

int i:33;//编译不过,因为int占用4个字节,32个比特位,所以最多定义到int i:32;

#include <stdio.h>

struct A{//char占用1个字节8个比特位,a b c各占用1个比特位,总共3个比特位,小于8个比特位,所以这个结构体占用1个字节
char a:1;
char b:1;
char c:1;
}A;
struct B{//char占用1个字节8个比特位,a b c总共占用8个比特位,正好是1个字节,所以这个结构体占用1个字节
char a:2;
char b:2;
char c:4;
}B;
struct B1{//char占用1个字节8个比特位,a b c总共占用9个比特位,超过1个字节,所以这个结构体占用2个字节
char a:2;
char b:2;
char c:5;
}B1;
struct C{//int占用4个字节32个比特位,a b总共占用32个比特位,正好4个字节,所以这个结构体占用4个字节
int a:31;
char b:1;
}C;
struct C1{//int占用4个字节32个比特位,a b总共占用33个比特位,超过4个字节,所以这个结构体占用8个字节,因为在char b处需要补3个字节
int a:31;
char b:2;
}C1;
struct C2{//即使结构体C2看起来只占用3个比特位,但是成员a是int类型,所以这个结构体占用4个字节
int a:1;
char b:2;
}C2; int main(){
printf("A:%ld\n", sizeof(A));
printf("B:%ld\n", sizeof(B));
printf("B1:%ld\n", sizeof(B1));
printf("C:%ld\n", sizeof(C)); //结构体C里的成员a占用32个比特位的后31个比特位;成员b占用第1个比特位
struct C sc;
sc.a =10;
sc.b = 1;
}
GDB的调试结果:
40 sc.a =10;
(gdb) p &sc//打印出sc.a的地址
$1 = (struct C *) 0x7fffffffdecc
(gdb) x/tw 0x7fffffffdecc//用二进制方式,产看内存地址里的值
0x7fffffffdecc: 00000000000000000000000000000000
(gdb) n
41 sc.b = 1;
(gdb) x/tw 0x7fffffffdecc//发现10被放到内存中了,1010就是十进制的10
0x7fffffffdecc: 00000000000000000000000000001010
(gdb) n
42 }
(gdb) x/tw 0x7fffffffdecc//发现1被放到内存的第一个比特位上了
0x7fffffffdecc: 10000000000000000000000000001010

运行结果:

A:1
B:1
B1:2
C:4
C1:8
C2:4

c/c++ 字节对齐的更多相关文章

  1. C语言:内存字节对齐详解[转载]

    一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...

  2. 字节对齐导致的iOS EXC_ARM_DA_ALIGN崩溃

    本文原链接: http://www.cnblogs.com/zouzf/p/4455167.html 先看一下这个链接:http://www.cnblogs.com/ren54/archive/201 ...

  3. ACE的CDR中的字节对齐问题

    大家应该都知道计算机中间都有字节对齐问题.CPU访问内存的时候,如果从特定的地址开始访问一般可以加快速度,比如在32位机器上,如果一个32位的整数被放在能被32模除等于0的地址上,只需要访问一次,而如 ...

  4. ARM字节对齐问题详解

    一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ...

  5. C语言之字节对齐

    在C语言编程中,有时为了达到减少运行的时间的目的,需要浪费一些空间:而有时为了节省空间,使它的运行时间增长.而字节对齐则是为了访问效率,用空间换取时间. 要掌握字节对齐,首先得明确一下四个概念: 1. ...

  6. C ~ C语言字节对齐

    1. 什么是对齐? 现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型 ...

  7. C语言的struct/union字节对齐

    C语言的一大优势就是对内存空间的控制,当然,一般情况下对于开发人员来说都是透明的.看一个始终困扰初学者的问题:字节对齐! 先看四个重要的基本概念:1.数据类型自身的对齐值:对于char型数据,其自身对 ...

  8. C++字节对齐问题

    关于C++字节对齐问题 关于C/C++的字节对齐 这两天写解析SWF文件的程序,在结构体指针和从文件里读出来的进行转换的时候遇到一些问题,就是有一个struct A,比如: struct A { ch ...

  9. C语言深入学习系列 - 字节对齐&内存管理

    用C语言写程序时需要知道是大端模式还是小端模式. 所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中:所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高 ...

  10. c++内存中字节对齐问题详解

    一.什么是字节对齐,为什么要对齐?    现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址 ...

随机推荐

  1. 让Python代码更快运行的 5 种方法

    不论什么语言,我们都需要注意性能优化问题,提高执行效率.选择了脚本语言就要忍受其速度,这句话在某种程度上说明了Python作为脚本语言的不足之处,那就是执行效率和性能不够亮.尽管Python从未如C和 ...

  2. Scala(一) —— 基础

    一.输出 println("Hello World") 二.变量与常量 1.变量用var表示,常量使用val表示 2.变量类型声明 var variableName : DateT ...

  3. 业务开发(一)—— MySQL

    0x01.SQL异常Incorrect string value java.sql.SQLException: Incorrect string value: '\xE6\x88\x91\xE7\x9 ...

  4. 【golang-GUI开发】struct tags系统(一)

    我们已经介绍了qt的signal和slot,现在该讲讲它的struct tags系统了.qt拥有多种的struct tags,我们会去一一了解它们. 什么是struct tags? struct ta ...

  5. iOS SQLite详解

    这周比较忙,前几天都加班到11点左右,基本都是到家都是12点左右(稍稍的抱怨一下,免费加班,何为免费,就是任何补偿都没有,例如调休,加班薪,餐补等各项福利,是一点都没有呀)因为App要上线了!App上 ...

  6. [翻译]一个新式的基于文本的浏览器 Browsh

    介绍 什么是Browsh? Browsh是一个纯文本浏览器,可以运行在大多数的TTY终端环境和任何浏览器.目前1 ,终端客户端比浏览器客户端更先进2. TTY 客户端 终端客户端即时更新和交付,以便于 ...

  7. 工作中常用Windows快捷键整理(1)-快速关闭网页

    打开桌面 win+D,显示桌面快捷键,不会关闭浏览器页面,是显示桌面. 关闭当前打开的所有标签页 Alt+F4,关闭当前打开的所有浏览器标签页. 关闭当前打开的标签页 Ctrl+W,关闭当前打开的标签 ...

  8. 第一次:lesson eighty seven。

    原文: A car crash. A:Is my car ready yet? B:I don't know sir,what's the number of your car? A:It's LFZ ...

  9. 自建Socket转发,使用远程桌面(mstsc)连接家中电脑

    网络结构图如下: 开题先放图,一切全靠编哈哈. 进入正题! 如图所示,我们需要一个公网服务器,利用公网服务器将内网的数据进行转发,从而实现两个内网服务器的通讯.没错,这不是p2p,原本想做成p2p,因 ...

  10. Java线程池 Executor框架概述

    线程池的意义 循环利用线程资源,避免重复创建和销毁线程 线程池的任务是异步执行的,只要提交完成就能快速返回,可以提高应用响应性 Java线程池还有一个很重要的意义:Java线程池就是JDK 5 推出的 ...