头图来源:かも仮面-#twitter


在C++中,内存访问地址必须是变量大小的整数倍(例如int32类型的变量大小为4个字节,那么该变量在内存中的地址必须能被4整除),这是为了保证数据的对齐和访问效率。如果一个变量的地址不是它的大小的整数倍,那么它可能会跨越两个或更多的内存单元,导致访问速度降低或者出现错误。为了避免这种情况,C++编译器会在内存分配时自动进行对齐,即在变量之间插入一些空白字节,使得每个变量的地址都是它的大小的整数倍。这样做虽然会浪费一些内存空间,但是可以提高程序的运行效率和稳定性。

下面是一个简单的例子,演示了C++中的内存对齐:

#include <iostream>
using namespace std;

struct A {
   char a; // 1 byte
   int b; // 4 bytes
   short c; // 2 bytes
};

struct B {
   char a; // 1 byte
   short b; // 2 bytes
   int c; // 4 bytes
};

int main() {
   cout << "sizeof(A) = " << sizeof(A) << endl; // output 12
   cout << "sizeof(B) = " << sizeof(B) << endl; // output 8
   return 0;
}

在这个例子中,结构体A和B都包含三个成员变量,分别占用1、4、2个字节。但是结构体A的大小是12个字节,而结构体B的大小是8个字节,为什么呢?这是因为编译器在分配内存时,会按照结构体中最大成员变量的大小进行对齐。对于结构体A来说,最大的成员变量是int类型的b,占用4个字节,所以编译器会在a和b之间插入3个空白字节,使得b的地址是4的整数倍;同理,在b和c之间也会插入2个空白字节,使得c的地址是2的整数倍。因此,结构体A的大小就是1+3+4+2+2=12个字节。而对于结构体B来说,最大的成员变量也是int类型的c,占用4个字节,但是由于a和b之间已经占用了3个字节,所以编译器不需要再插入任何空白字节,直接将c放在下一个4字节边界处。因此,结构体B的大小就是1+2+4=8个字节。

从这个例子可以看出,内存对齐可以影响到数据结构的大小和布局,所以在设计数据结构时要注意成员变量的顺序和类型,尽量减少空白字节的浪费。同时,在使用指针访问内存时也要注意对齐问题,否则可能会出现意想不到的结果。

Last modification:September 1st, 2023 at 02:54 pm
If you think my article is useful to you, please feel free to appreciate