内存字节对齐

iOS开发-内存字节对齐原理 内存字节对齐现象 我们首先通过两个结构体来观察iOS的内存字节对齐的现象。 struct StructOne { char a; //1字节 double b; //8字节 int c; //4字节 short d; //2字节 } MyStructOne; struct StructTwo { double b; //8字节 int c; //4字节 shor 阅读详情
 
1. 定义:
    sizeof是何方神圣?

    sizeof 乃 C/C++ 中的一个操作符(operator)是也。简单说其作用就是返回一个对象或者类型所占的内存字节数。

MSDN上的解释为:

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types).This keyword returns a value of type size_t.

    其返回值类型为size_t,在头文件stddef.h中定义。这是一个依赖于编译系统的值,一般定义为

typedef unsigned int size_t;

    世上编译器林林总总,但作为一个规范,它们都会保证char、signed char和unsigned char的sizeof值为1,毕竟char是我们编程能用的最小数据类型。

2. 语法:
    sizeof有三种语法形式,如下:
    1) sizeof( object );    // sizeof( 对象 );
    2) sizeof( type_name ); // sizeof( 类型 );
    3) sizeof object;       // sizeof 对象;

所以,
int i;
sizeof( i );     // ok
sizeof i;        // ok
sizeof( int );   // ok
sizeof int;      // error

既然写法2可以用写法1代替,为求形式统一以及减少我们大脑的负担,第2种写法,忘掉它吧!

实际上,sizeof计算对象的大小也是转换成对对象类型的计算。也就是说,同种类型的不同对象其sizeof值都是一致的。

这里,对象可以进一步延伸至表达式,即sizeof可以对一个表达式求值。编译器根据表达式的最终结果类型来确定大小,一般不会对表达式进行计算。

例如:

sizeof( 2 );        // 2的类型为int,所以等价于 sizeof( int );
sizeof( 2 + 3.14 ); // 3.14的类型为double,2也会被提升成double类型,所以等价于 sizeof( double );

    sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用。我们来看一个完整的例子:

*********************************************************

char foo()
{
    printf("foo() has been called./n");
    return 'a';
}
int main()
{
    size_t sz = sizeof( foo() );   // foo() 的返回值类型为char,所以sz = sizeof(char),但函数foo()并不会被调用
    printf("sizeof( foo() ) = %d/n", sz);
}

*********************************************************

C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的:

    sizeof( foo );     // error
    void foo2() { }
    sizeof( foo2() );  // error
    struct S
    {
        unsigned int f1 : 1;
        unsigned int f2 : 5;
        unsigned int f3 : 12;
    };
    sizeof( S.f1 );   // error


3. sizeof的常量性


    sizeof的计算发生在编译时刻,所以它可以被当作常量表达式使用。如:

char ary[ sizeof( int ) * 10 ];   // ok

最新的C99标准规定sizeof也可以在运行时刻进行计算。如下面的程序在Dev-C++中可以正确执行:

int n;
n = 10;        // n动态赋值
char ary[n];   // C99也支持数组的动态定义
printf("%d/n", sizeof(ary)); // ok. 输出10

但在没有完全实现C99标准的编译器中就行不通了,上面的代码在VC6中就通不过编译。所以我们最好还是认为sizeof是在编译期执行的,这样不会带来错误,让程序的可移植性强些。


4. 基本数据类型的sizeof

这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型。由于它们都是和系统相关的,所以在不同的系统下取值可能不同。这务必引起我们的注意,尽量不要在这方面给自己程序的移植造成麻烦。

一般的,在32位编译环境中,sizeof(int)的取值为4。


5. 指针变量的sizeof

学过数据结构的你应该知道指针是一个很重要的概念,它记录了另一个对象的地址。既然是来存放地址的,那么它当然等于计算机内部地址总线的宽度。所以在32位计算机中,一个指针变量的返回值必定是4(注意结果是以字节为单位)。可以预计,在将来的64位系统中指针变量的sizeof结果为8。

*********************************************************

char* pc = "abc";
int* pi;
string* ps;
char** ppc = &pc;
void (*pf)(); // 函数指针
sizeof( pc ); // 结果为4
sizeof( pi ); // 结果为4
sizeof( ps ); // 结果为4
sizeof( ppc );// 结果为4
sizeof( pf ); // 结果为4

*********************************************************

指针变量的sizeof值与指针所指的对象没有任何关系,正是由于所有的指针变量所占内存大小相等,所以MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构(使用指向结构体的指针)。


6. 数组的sizeof

数组的sizeof值等于数组所占用的内存字节数,如:

char a1[] = "abc";
int a2[3];
sizeof( a1 ); // 结果为4,字符 末尾还存在一个NULL终止符
sizeof( a2 ); // 结果为3*4=12(依赖于int)

一些朋友刚开始时把sizeof当作了求数组元素的个数,现在,你应该知道这是不对的。那么应该怎么求数组元素的个数呢?

Easy,通常有下面两种写法:

int c1 = sizeof( a1 ) / sizeof( char );    // 总长度/单个元素的长度
int c2 = sizeof( a1 ) / sizeof( a1[0]);    // 总长度/第一个元素的长度


写到这里,提一问,下面的c3,c4值应该是多少呢?

*********************************************************

void foo3(char a3[3])
{
    int c3 = sizeof( a3 ); // c3 ==
}
void foo4(char a4[])
{
    int c4 = sizeof( a4 ); // c4 ==
}

*********************************************************

也许当你试图回答c4的值时已经意识到c3答错了,是的,c3!=3。

这里函数参数a3已不再是数组类型,而是蜕变成指针。相当于char* a3,为什么仔细想想就不难明白。

我们调用函数foo1时,程序会在栈上分配一个大小为3的数组吗?不会!

数组是“传址”的,调用者只需将实参的地址传递过去,所以a3自然为指针类型(char*),c3的值也就为4。


7. 结构体的sizeof

这是初学者问得最多的一个问题,所以这里有必要多费点笔墨。让我们先看一个结构体:

struct S1
{
    char c;
    int i;
};

问sizeof(s1)等于多少?

聪明的你开始思考了,char占1个字节,int占4个字节,那么加起来就应该是5。

是这样吗?

你在你机器上试过了吗?

也许你是对的,但很可能你是错的!

VC6中按默认设置得到的结果为8。

    Why?为什么受伤的总是我?

请不要沮丧,我们来好好琢磨一下sizeof的定义 —— sizeof的结果等于对象或者类型所占的内存字节数。好吧,那就让我们来看看S1的内存分配情况:

S1 s1 = { 'a', 0xFFFFFFFF };

定义上面的变量后,加上断点,运行程序,观察s1所在的内存,你发现了什么?

以我的VC6.0为例,s1的地址为0x0012FF78,其数据内容如下:

0012FF78: 61 CC CC CC FF FF FF FF

发现了什么?怎么中间夹杂了3个字节的CC?

看看MSDN上的说明:

When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.

原来如此,这就是传说中的字节对齐啊!一个重要的话题出现了。

为什么需要字节对齐?

计算机组成原理教导我们,这样有助于加快计算机的取数速度,否则就得多花指令周期了。

为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short等)都位于能被2整除的地址上,让宽度为4的基本数据类型(int等)都位于能被4整除的地址上。以此类推,这样,两个数中间就可能需要加入填充字节,所以整个结构体的sizeof值就增长了。

让我们交换一下S1中char与int的位置:

struct S2
{
    int i;
    char c;
};

看看sizeof(S2)的结果为多少?怎么还是8。

再看看内存,原来成员c后面仍然有3个填充字节。

这又是为什么啊?别着急,下面总结规律。

    字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

    对于上面的准则,有几点需要说明:
1) 前面不是说结构体成员的地址是其大小的整数倍,怎么又说到偏移量了呢?

因为有了第1点存在,所以我们就可以只考虑成员的偏移量,这样思考起来简单。想想为什么。

结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得,这个宏也在stddef.h中定义,如下:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

例如,想要获得S2中c的偏移量,方法为

size_t pos = offsetof(S2, c);// pos等于4


2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型。这里所说的“数据宽度”就是指其sizeof的大 小。由于结构体的成员可以是复合类型,比如另外一个结构体,所以在寻找最宽基本类型成员时,应当包括复合类型成员的子成员,而不是把复合成员看成是一个整 体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。

这里叙述起来有点拗口,思考起来也有点挠头,还是让我们看看例子吧(具体数值仍以VC6为例,以后不再说明):

struct S3
{
    char c1;
    S1 s;
    char c2;
};

S1的最宽简单成员的类型为int,S3在考虑最宽简单类型成员时是将S1“打散”看的,所以S3的最宽简单类型为int。这样,通过S3定义的变量,其存储空间首地址需要被4整除,整个sizeof(S3)的值也应该被4整除。

c1的偏移量为0,s的偏移量呢?这时s是一个整体,它作为结构体变量也满足前面三个准则,所以其大小为8,偏移量 为4,c1与s之间便需要3个填充字节,而c2与s之间就不需要了,所以c2的偏移量为12,算上c2的大小为13,13是不能被4整除的,这样末尾还得 补上3个填充字节。最后得到sizeof(S3)的值为16。


    通过上面的叙述,我们可以得到一个公式:
    结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目,即:

sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding )

 

8.类的sizeof
 
类的sizeof值等于类中成员变量所占用的内存字节数。如:
****************************************************************
 
class A
{
 public:
     int b;
     float c;
     char d;
};

int main(void)
{
  A object;
  cout << "sizeof(object) is " << sizeof(object) << endl;
  return 0 ;
}
 
***************************************************************
 
 
输出结果为12(我的机器上sizeof(float)值为4,字节对其前面已经讲过)。
 
不过需要注意的是,如果类中存在静态成员变量,结果又会是什么样子呢?
 
***************************************************************

class A
{
 public:
     static int a;
     int b;
     float c;
     char d;
};

int main()
{
  A object;
  cout << "sizeof(object) is " << sizeof(object) << endl;
  return 0 ;
}
 
**************************************************************
 
 
16?不对。结果仍然是12.

因为在程序编译期间,就已经为static变量在静态存储区域分配了内存空间,并且这块内存在程序的整个运行期间都存在。

而每次声明了类A的一个对象的时候,为该对象在堆上,根据对象的大小分配内存。
 
如果类A中包含成员函数,那么又会是怎样的情况呢?看下面的例子
 
*************************************************************

class A
{
 public:
     static int a;
     int b;
     float c;
     char d;
     int add(int x,int y)
     {
       return x+y;
     }
};

int main()
{
  A object;
  cout << "sizeof(object) is " << sizeof(object) << endl;
  b = object.add(3,4);
  cout << "sizeof(object) is " << sizeof(object) << endl;
  return 0 ;
}
 
***************************************************************
 
结果仍为12。
 
因为只有非静态类成员变量在新生成一个object的时候才需要自己的副本。
所以每个非静态成员变量在生成新object需要内存,而function是不需要的。
 
 
注:C++中的多态和虚继承也是非常重要的东西,不过比较复杂,编译器不同,细节也有所不同。 
////////////////////////////////////////////////////////////////////////////////////////////////////////


朋友帖了如下一段代码:
  #pragma pack(4)
  class TestB
  {
  public:
    int aa;
    char a;
    short b;
    char c;
  };
  int nSize = sizeof(TestB);
  这里nSize结果为12,在预料之中。

  现在去掉第一个成员变量为如下代码:
  #pragma pack(4)
  class TestC
  {
  public:
    char a;
    short b;
    char c;
  };
  int nSize = sizeof(TestC);
  按照正常的填充方式nSize的结果应该是8,为什么结果显示nSize为6呢?

事实上,很多人对#pragma pack的理解是错误的。
#pragma pack规定的对齐长度,实际使用的规则是:
结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,
按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不
产生任何效果。
而结构整体的对齐,则按照结构体中最大的数据成员 和 #pragma pack指定值 之间,较小
的那个进行。

具体解释
#pragma pack(4)
  class TestB
  {
  public:
    int aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以
这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以
放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置。
  };
这个类实际占据的内存空间是9字节
类之间的对齐,是按照类内部最大的成员的长度,和#pragma pack规定的值之中较小的一
个对齐的。
所以这个例子中,类之间对齐的长度是min(sizeof(int),4),也就是4。
9按照4字节圆整的结果是12,所以sizeof(TestB)是12。


如果
#pragma pack(2)
    class TestB
  {
  public:
    int aa; //第一个成员,放在[0,3]偏移的位置,
    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以
这个成员按一字节对齐,放在偏移[4]的位置。
    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以
放在偏移[6,7]的位置。
    char c; //第四个,自身长为1,放在[8]的位置。
  };
//可以看出,上面的位置完全没有变化,只是类之间改为按2字节对齐,9按2圆整的结果是
10。
//所以 sizeof(TestB)是10。

最后看原贴:
现在去掉第一个成员变量为如下代码:
  #pragma pack(4)
  class TestC
  {
  public:
    char a;//第一个成员,放在[0]偏移的位置,
    short b;//第二个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以
放在偏移[2,3]的位置。
    char c;//第三个,自身长为1,放在[4]的位置。
  };
//整个类的大小是5字节,按照min(sizeof(short),4)字节对齐,也就是2字节对齐,结果
是6
//所以sizeof(TestC)是6。

感谢 Michael 提出疑问,在此补充:

当数据定义中出现__declspec( align() )时,指定类型的对齐长度还要用自身长度和这里
指定的数值比较,然后取其中较大的。最终类/结构的对齐长度也需要和这个数值比较,然
后取其中较大的。

可以这样理解, __declspec( align() ) 和 #pragma pack是一对兄弟,前者规定了对齐
的最小值,后者规定了对齐的最大值,两者同时出现时,前者拥有更高的优先级。
__declspec( align() )的一个特点是,它仅仅规定了数据对齐的位置,而没有规定数据实
际占用的内存长度,当指定的数据被放置在确定的位置之后,其后的数据填充仍然是按照
#pragma pack规定的方式填充的,这时候类/结构的实际大小和内存格局的规则是这样的:

在__declspec( align() )之前,数据按照#pragma pack规定的方式填充,如前所述。当遇
到__declspec( align() )的时候,首先寻找距离当前偏移向后最近的对齐点(满足对齐长
度为max(数据自身长度,指定值) ),然后把被指定的数据类型从这个点开始填充,其后的
数据类型从它的后面开始,仍然按照#pragma pack填充,直到遇到下一个__declspec( al
ign() )。
当所有数据填充完毕,把结构的整体对齐数值和__declspec( align() )规定的值做比较,
取其中较大的作为整个结构的对齐长度。
特别的,当__declspec( align() )指定的数值比对应类型长度小的时候,这个指定不起作
用。

字节对齐对内存访问效率的影响 对齐的数据能够更高效地被处理器读取,而未对齐的数据则可能需要额外的操作来满足对齐要求,从而导致性能下降。在处理器访问内存时,对齐的数据可以按照较快的方式进行读取,而不需要进行额外的处理。相反,未对齐的数据则需要处理器进行额外的操作,以满足对齐要求。在大多数系统中,int类型的字节大小为4,而char类型的字节大小为1。然而,由于对齐要求,该结构体实际上会被填充为8个字节,以满足4字节对齐的要求。由于MyStruct的对齐要求,访问myArray中的成员变量时,处理器可能需要进行额外的操作来获取正确的数据。 阅读详情

相关推荐

竞赛无人机模块化开发实战:2023 TI电赛G题空地协同消防系统(飞控与视觉融合篇)

本文以2023年TI电赛G题为例,详细阐述了采用模块化开发思维构建空地协同智能消防系统的实战方法。文章重点拆解了无人机飞控二次开发、视觉识别与融合控制等核心模块,提供了硬件选型、代码实现与系统联调的完整指南,旨在帮助参赛者通过“搭积木”式编程高效完成复杂系统集成。

js777的博客 454

字节对齐详解

一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平...

weixin_34405925的博客 220

python制作图形化小游戏_创意编程|Python的GUI简易界面设计测测你的反应力

Python的GUI简易界面设计案例测测你的反应力作为初次接触代码编程的你,是不是觉得Python程序除了“码”就是“字”即使是有趣的程序除了烧烧自己的脑,也吸引不到更多人的兴趣,用户体验值接近于0?那你可冤枉了Python,他可是人工智能界的编程语言大咖。今天这个游戏设计就先带领大家,简单体验一下,如何让Python程序图形化。一起来吧!设计我们的小游戏游戏设计思路:电脑随机出...

weixin_34214135的博客 1872

字节对齐看这篇就够了(内存对齐)

大家好,我是小昭,因为在不同硬件平台数据传输时,遇到关于字节对齐的问题,索性就做了总结,以下是我对字节对齐的理解和小结,如有疑问请联系我。

不断debug,优化中…… 9877

宋浩线性代数笔记

Miao-A-SongHao-Linear-Algebra-Notes bilibili 宋浩老师 “惊叹号” 系列 《线性代数》网课 笔记及时间点目录 Github项目地址:https://github.com/cy69855522/Miao-A-SongHao-Linear-Algebra-Notes ???? 前言 我发现吧,线代没记笔记真不行。 浩浩学习,天天向上。数学网课推荐????宋浩老师的免...

Knife丶小刀博客 4万+

LAMMPS模拟新合金没势函数?手把手教你用`pair_style hybrid`混合势函数(附FeCMnSiTi案例)

本文详细介绍了在LAMMPS中如何使用`pair_style hybrid`混合势函数模拟新型高熵合金(如FeCMnSiTi),解决缺乏现成势函数的问题。通过实战案例,涵盖参数查找、命令编写、错误排查等关键步骤,特别适合处理多组元体系的复杂相互作用。文章还提供了EAM势函数与LJ势的组合技巧,帮助研究者准确模拟合金性能。

weixin_30635053的博客 244

c++内存字节对齐

内存字节对齐 对齐的三个原则 如何内存对齐?sizeof的结果怎么来的?请记住以下3条原则:(在没有#pragma pack宏的情况下) 原则1:结构(struct)或联合(union)的数据成员,存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如:假设一个数据成员为int,int在32位机上为4字节,则要从4的整数倍地址开始存储) ...

Bruce 209

Librepilot _64位window10环境下的搭建及一些坑的解决办法

  刚入IT行业的小菜鸟,在window上折腾了四天的librepilot地面控制站的搭建,想着这么辛苦不能白费了,看网上相关资料少得可怜,唯一一个详细教程还是在32位环境下,一大堆坑,所以把自己的经验写下来,供大家一起参考。 参考的原文是:https://www.cnblogs.com/jasonchan1202/p/7809937.html的博客,但是执行下来才发现这个博客对64位系统极其不...

weixin_41426339的博客 2728

FreeRTOS内存管理中字节对齐的理解

FreeRTOS内存申请函数pvPortMalloc()字节对齐的语句如下 1.申请内存数字节对齐 xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); xWantedSize 是要申请的字节数 portBYTE_ALIGNMENT是字节对齐数 ...

qcmc123的专栏 4123

Prompt Airlines CTF通关实战:从提示词注入到多模态攻击的AI安全攻防演练

提示词注入(Prompt Injection)是当前大语言模型(LLM)应用面临的核心安全威胁之一,其原理在于攻击者通过精心构造的用户输入,覆盖或绕过系统预设的指令,从而操控模型行为。这种攻击手法的技术价值在于揭示了AI系统在理解与执行指令时存在的逻辑边界模糊性,可能导致数据泄露、越权访问等严重风险。在应用场景上,从基础的客服对话到结合视觉识别的多模态系统,都可能成为攻击面。本文以一场名为“Prompt Airlines CTF”的实战挑战为例,深入剖析了包括指令遗忘、上下文注入、工具调用滥用及多模态提示注

aodan5477的博客 518

低功耗基础概念——Level Shifter cell补充

信号跨越不同级别电压模块进行驱动时,需要使用level shifter。 H2L Level shifer 从高电压到低电压的level shifter,可以是两个反相器的串联。 输入高电平区域信号INH,输出低电平区域信号OUTL,注意供应电源由低电压模块提供,即图中的VDDL。 从图中可以看出,H2L的level shifter只会引入一个buffer的延迟,对时序的影响较小。 L2H Level shifer 用低电压区域的信号invert和buffer之后得到的一对信号来驱动工作在高电压区域的交

qq_36480087的博客 1万+

字节对齐与CPU效率和内存占用

由于C++的项目做的少,又比较小,所以一直没有注意字节对齐的问题,但是,字节对齐在大规模应用中对内存管理和CPU执行效率的影响应是挺大的。本文根据一些资料学习,做一个小总结。 首先抛出第一个结论,字节对齐可以提高CPU的执行效率。 根据(1)中分析,CPU执行指令时从内存中获取数据是按块操作的,块的大小可能为2-bytes, 4-bytes, 8-bytes, 16-bytes……

aitazhixin的专栏 2552

AI测试:手把手教你用AI做桌面自动化「喂饭教程」

本文介绍了基于MCP协议的DesktopCommanderMCP自动化工具,通过自然语言指令实现桌面操作。系统采用客户端-服务器架构,支持应用程序管理、文件操作、屏幕控制等功能。详细说明了环境搭建步骤,包括Python和Node.js依赖安装、API密钥配置及MCP服务部署。通过实战案例展示了文件整理、批量截图等典型应用场景,并分享了任务描述优化、权限控制等最佳实践。该方案能显著提升重复性桌面操作的效率,让AI成为智能办公助手。

blues_C的博客 851

字节对齐与内存访问

关于字节对齐,最早是在《高质量程序设计》中看到的,当时明白一点,就是因为定义的数据字节大小不一(1字节,2字节,4字节,8字节),在内存中可能会有字节对齐的操作,就是数据在内存中的排放,不一定是连续的。因此也产生了一个疑问,就是对于数组而言,特别是结构体,如果不连续排放了。那么,当我们将结构体,当做连续的一段内存来访问时, 是不是会造成错误呢? 当时,虽然有疑惑,但是一直没有特别明白的

tietao的专栏 7984

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C++ 内存的字节对齐

一、字节对齐的原因            在访问内存时,如果地址是按4字节对齐,则访问效率会高很多。这种现象的原因在于访问内存的硬件电路。一般情况下,地址总线总是按照对齐后的地址来访问。例如,你想得到0x00000001开始的四字节内容,系统首先需要以0x00000000读四字节,从中取得3字节,然后再用0x00000004作为开始地址,获得下一个4字节,再从中得到第一个字节,再次组合出需要得到

u011974126的专栏 1302

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

内存字节对齐、为什么要对齐

内容会持续更新,有错误的地方欢迎指正,谢谢! 内存字节对齐 对齐的三个原则 如何内存对齐?sizeof的结果怎么来的?请记住以下3条原则:(在没有#pragma pack宏的情况下) 原则1:结构(struct)或联合(union)的数据成员,存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如:假设一个数据成员为int,i...

陈云佳的专栏 2254

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

C语言内存字节对齐小结

在C语言面试和考试中经常会遇到内存字节对齐的问题。今天就来对字节对齐的知识进行小结一下。 首先说说为什么要对齐。为了提高效率,计算机从内存中取数据是按照一个固定长度的。以32位机为例,它每次取32个位,也就是4个字节(每字节8个位,计算机基础知识,别说不知道)。字节对齐有什么好处?以int型数据为例,如果它在内存中存放的位置按4字节对齐,也就是说1个int的数据全部落在计算机一次取数的区间内,那

andy572633的专栏 3万+

结构体的内存空间分配及字节对齐

关于内存对齐 一: 1.什么是内存对齐 假设我们同时声明两个变量: char a; short b; 用&(取地址符号)观察变量a, b的地址的话,我们会发现(以16位CPU为例): 如果a的地址是0x0000,那么b的地址将会是0x0002或者是0x0004。 那么就出现这样一个问题:0x0001这个地址没有被使用,那它干什么去了?答案就是它确实没被使用。因为C

Epic丶玖遇 1788

java 字节对齐_内存字节对齐-

一、概念对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。二、为什么要字节对齐需要字节对齐的根本原因在于CPU访问数据的效率问题。假设上面整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002...

weixin_36219894的博客 662

内存字节对齐问题

刚才工作的时候跟一同事突然问起内存对齐问题,但是自己突然又想不起来,关于内存字节对齐,我想大家都一样,看了忘、然后下次再碰到的时候还得继续查,所以比较苦恼! 下面我就根据自己的总结来说下这个内存

假装在纽约 1817

【已解决】C++中由于字节对齐引起的踩内存问题

C++中由于字节对齐引起的踩内存问题 问题现象 最近遇到了一个奇怪的问题,在创建对象时程序异常退出,具体地,在构造函数中访问类中最后一个成员变量时,程序异常退出。 问题定位 查看代码,发现该类中有一个结构体数组,该结构体在类的外面声明,用 #pragma pack(push,1) 设置了一字节对齐方式,而类不在这个作用范围内,所以是按照默认字节对齐方式的。怀疑该问题是因为,类的字节对齐方式和类中的结构体字节方式不同引起的。但这从理论方面解释不通。 继续定位,在创建对象之前用sizeof打印类的大小,再在类的

WINGREZ‘S BLOG 2027

内存分配,任意字节对齐

内存分配,任意字节对齐 有这么一道题目,要求按任意字节对齐分配内存,接口: char* aligned_malloc(int size,int alignment)//size为分配的内存大小,alignment对齐基数(可以为任意数) 这个在gcc库函数里能找到源码,在ffdshow等开源代码里面也能找到源码,实现如下: void* aligned_malloc(int size,int ali...

qq_27435605的博客 392
上一篇: IEEE754 浮点数表示
下一篇: linux汇编之命令行参数
mindview
博客等级 码龄19年 7粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值