内存对齐

java中printf中用法详解

蹲街弑〆低调 提交于 2019-12-05 02:52:39
看到这篇文章写得不错,情不自禁转载 本文章转载自 https://www.cnblogs.com/seakt/p/4478045.html 目前printf支持以下格式: %c 单个字符 %d 十进制整数 %f 十进制浮点数 %o 八进制数 %s 字符串 %u 无符号十进制数 %x 十六进制数 %% 输出百分号% printf的格式控制的完整格式: % - 0 m.n l或h 格式字符 下面对组成格式说明的各项加以说明: ①%:表示格式说明的起始符号,不可缺少。 ②-:有-表示左对齐输出,如省略表示右对齐输出。 ③0:有0表示指定空位填0,如省略表示指定空位不填。 ④m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为n=6位。 ⑤l或h:l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型。 --------------------------------------- 格式字符 格式字符用以指定输出项的数据类型和输出格式。 ①d格式:用来输出十进制整数。有以下几种用法: %d:按整型数据的实际长度输出。 %md:m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出。 %ld:输出长整型数据。 ②o格式:以无符号八进制形式输出整数

内存编址和寻址、内存对齐

主宰稳场 提交于 2019-12-05 01:58:44
内存编址方式 1.内存在逻辑上就是一个一个的格子,这些格子可以用来装东西,也就是内存中的数据,每个格子都有一个固定的编号,这个编号0、1、2、3就是 内存地址,这个内存地址(一个数字)和这个格子的空间是一一对应的并且是永久绑定的。这就是 内存的编址方式 2.在程序运行时,CPU只认识内存地址,而不关心这个地址所代表的空间在哪里以及分布,因为硬件的设计保证了只要有地址,就一定能找到这个盒子在 哪里,所以内存单元有两个概念:地址和空间 3.内存编址是以字节为单位,每一个内存地址对应的内存大小的空间是固定的,就是一个字节8bit 内存寻址方式 1.逻辑地址:包含在机器语言指令中用来指定一个操作数或者一条指令的地址 2.线性地址(也称虚拟地址):是一个32位无符号整数,可以用来表示高达4G的地址,通常使用16进制数来表示,范围从0x00000000到0xffffffff 3.物理地址:用于内存芯片级内存单元寻址,他们从微处理器的地址引脚发送到内存总线上的电信号相对应。物理地址由32位或36位无符号整数表示 MMU MMU内存管理单元)的功能是将逻辑地址转换为物理地址,其中包括: 1.分页单元,将逻辑地址转换为线性地址 2.分页单元,将线性地址转换为物理地址 内存对齐 typedef abc{ char a; short b; int c; } typedef my{ char a; int

结构体对齐详解【转】

走远了吗. 提交于 2019-12-05 00:26:45
转自: https://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html 1 -- 结构体数据成员对齐的意义 许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。 比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。 2 -- 结构体对齐包括两个方面的含义 1)结构体总长度; 2)结构体内各数据成员的内存对齐,即该数据成员相对结构体的起始位置; 3 -- 结构体大小的计算方法和步骤 1)将结构体内所有数据成员的长度值相加,记为sum_a; 2)将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragma pack指定的数值以及该数据成员自身长度中数值较小者

sizeof、strlen之一

半腔热情 提交于 2019-12-04 18:44:43
解析C/C++语言中的sizeof 一、sizeof的概念   sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 二、sizeof的使用方法   1、用于数据类型   sizeof使用形式:sizeof(type)   数据类型必须用括号括住。如sizeof(int)。   2、用于变量   sizeof使用形式:sizeof(var_name)或sizeof var_name   变量名可以不用括号括住。如sizeof (var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。   注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。   如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式。 三、sizeof的结果    sizeof 操作符的结果类型是size_t

类与对象(上) C++

感情迁移 提交于 2019-12-04 14:48:36
深夜发博,最深的感触就是,曾经欠的债,是要用头发来还的…… 关于C++大致分为以下几个小部分: 1.类与对象的初步认知: C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。 2.类的引入: C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。结构体的定义,在C++中更喜欢用class来代替 ,然后将这种把函数与变量等绑定在一个结构体中,这个结构体称为类。 struct Student1 { void SetStudentInfo(const char* name, const char* gender, int age) { strcpy(_name, name); strcpy(_gender, gender); _age = age; } void PrintStudent() { cout << _name << " " << _gender << " " << _age << endl; } char _name[20]; char _gender[10]; int _age; }; class Student2 { public: void SetStudentInfo(const char* name, const

逆向-PE头解析

与世无争的帅哥 提交于 2019-12-04 11:35:49
目录 PE头解析 数据结构 IMAGE_DOS_HEADER IMAGE_NT_HEADERS 区块 PE头解析 PE 格式是Windows系统下组织可执行文件的格式。PE文件由文件头和对应的数据组成。目标是在不同的架构下装载器和编程工具不用重写。 PE中一大特点是不连续的位置大部分记录的都是相对地址(RVA),相对的是PE文件中记录的基地址(image base)的偏移量。进程是程序的执行状态的实体,每个进程都有自己独立的内存空间(编址)PE和内核等一起编制,所以image base也不总是确定的。 结构(参考:加密与解密) 数据结构 IMAGE_DOS_HEADER 参考:参考: http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf IMAGE_DOS_HEADER STRUCT { +0h WORD e_magic //Magic DOS signature MZ(4Dh 5Ah) DOS可执行文件标记 +2h WORD e_cblp //Bytes on last page of file +4h WORD e_cp //Pages in file +6h WORD e_crlc //Relocations +8h WORD e_cparhdr //Size of header in

__attribute__机制介绍

邮差的信 提交于 2019-12-04 04:54:05
1. __attribute__ GNU C 的一大特色(却不被初学者所知)就是 __attribute__ 机制。 __attribute__ 可以设置函数属性 (Function Attribute) 、变量属性 (Variable Attribute) 和类型属性 (Type Attribute) __attribute__ 前后都有两个下划线,并且后面会紧跟一对原括弧,括弧里面是相应的 __attribute__ 参数 __attribute__ 语法格式为: __attribute__ ( ( attribute-list ) ) 函数属性( Function Attribute ),函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。 __attribute__ 机制也很容易同非 GNU 应用程序做到兼容。 GNU CC 需要使用 –Wall ,这是控制警告信息的一个很好的方式。下面介绍几个常见的属性参数。 2. format 该属性可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配 。它可以给被声明的函数加上类似 printf 或者 scanf 的特征,该功能十分有用,尤其是处理一些很难发现的 bug 。 format 的语法格式为: format ( archetype, string-index,

C语言字节对齐问题详解

我怕爱的太早我们不能终老 提交于 2019-12-04 03:48:45
本文转自: https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 short s; 4 char c2; 5 int i; 6 }T_FOO; 假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4。 现在,我们编写一个简单的程序: 1 int main(void){ 2 T_FOO a; 3 printf("c1 -> %d, s -> %d, c2 -> %d, i -> %d\n", 4 (unsigned int)(void*)&a.c1 - (unsigned int)(void*)&a, 5 (unsigned int)(void*)&a.s - (unsigned int)(void*)&a, 6 (unsigned int)(void*)&a.c2 - (unsigned int)(void*)&a, 7 (unsigned int)(void*)&a.i - (unsigned int)(void*)&a); 8 return 0; 9 } 运行后输出: 1 c1 -> 0, s -> 2, c2 -> 4, i -> 8 为什么会这样?这就是字节对齐导致的问题。

关于结构体大小一篇很详细的文章

有些话、适合烂在心里 提交于 2019-12-03 23:08:30
## 前言 ## 在计算机中数据存储和传输以位(bit)为单位,每8个位bit组成1个字节(Byte)。32位计算机的字长为32位,即4个字节;对应的,64位计算机的字长为64位,即8个字节。计算机系统对基本类型数据在内存中存放的位置有限制,要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。 ## 结构的存储分配 ## 编译器按照结构体成员列表的顺序为每个成员分配内存,当存储成员时需要满足正确地边界对齐要求时,成员之间可能出现用于填充地额外内存空间。32位系统每次分配字节数最多为4个字节,64位系统分配字节数最多为8个字节。 以下图表是在不同系统中基本类型数据内存大小和默认对齐模数: 注:此外指针所占内存的长度由系统决定,在32位系统下为32位(即4个字节),64位系统下则为64位(即8个字节). ## 没有#pragma pack宏的对齐 ## **对齐规则** : (1)结构体的起始存储位置必须是能够被该结构体中最大的数据类型所整除。 (2)每个数据成员存储的起始位置是自身大小的整数倍(比如int在32位机为4字节,则int型成员要从4的整数倍地址开始存储)。 (3)结构体总大小(也就是sizeof的结果),必须是该结构体成员中最大的对齐模数的整数倍。若不满足

C语言字节对齐问题

匿名 (未验证) 提交于 2019-12-03 00:34:01
一、什么是字节对齐 特定类型变量 时经常在 特定的内存地址 访问,这就需要各种类型数据 按照一定的规则 在空间上排列,而不是顺序的一个接一个的存放,这就是对齐。 二、对齐的原因和作用 存取效率上的损失。 合理的内存对齐可以提高访问效率。为使得CPU能对数据进行快速访问,数据的起始地址应具有“对齐”特性。 参考文献:http://www.cnblogs.com/clover-toeic/p/3853132.html#3943789 文章来源: C语言字节对齐问题