堆栈中数组之间的 C++ 间隙
C++ gap between arrays in stack
此代码的输出:
int a;
int b;
cout<<"a: "<<&a<<endl;
cout<<"b: "<<&b<<endl;
是:
a: 0x6ffe4c
b: 0x6ffe48
这是有道理的,它们之间应该相差 4 个字节,但是这段代码的输出:
int A[1];
int B[1];
cout<<"A: "<<A<<endl;
cout<<"B: "<<B<<endl;
是:
A: 0x6ffe40
B: 0x6ffe30
所以现在相差了 16 个字节,谁能解释为什么?为什么需要这个差距?当你像这样分配数组时,我不知道堆栈中存在间隙,并认为在这种情况下 B[1] 与 A[0] 相同。
C 和 C++ 都不保证自动变量在内存中的顺序,或者它们之间的任何填充。这些是您的特定编译器的实现细节。
为了解释您的实例中数组变量之间的间隙,您将需要研究 GNU C++ 编译器如何为变量分配内存。变量的分配取决于编译器。
变量之间存在差距的一些原因(不包括在内):
对齐
当处理器可以从与其字长对齐的地址中获取数据时,它们的效率会更高。例如,具有 32 位字的处理器喜欢从 4 字节对齐的地址中获取数据。从地址 5 访问 32 位将需要两次获取,然后进行一些字节移位以将字节按正确的顺序放置。
数据段
常量变量可以放在可执行文件或只读数据段中。它可以在 read/write 变量旁边声明,因此它们之间有一个间隙日志。
超限space
编译器可能会在数组后分配 space 以在数组溢出的情况下提供 "buffering"。
元信息
编译器可能会选择将有关数据类型的属性 (Meta) 信息放在数据类型之后(或之前)。例如,当为数组动态分配内存时,编译器可能会选择将分配的大小放在数组附近(对于回收内存很有用)。
注册
编译器可能会将变量放在寄存器中。因此变量会有不同的地址,因为寄存器通常不在同一个内存映射中;尽管有些处理器具有内存映射寄存器。
正在解析
变量可以分配在便于解析的位置。编译器可能会延迟变量分配,直到方便为止,或者在优化过程中可能会更改位置。
此代码的输出:
int a;
int b;
cout<<"a: "<<&a<<endl;
cout<<"b: "<<&b<<endl;
是:
a: 0x6ffe4c
b: 0x6ffe48
这是有道理的,它们之间应该相差 4 个字节,但是这段代码的输出:
int A[1];
int B[1];
cout<<"A: "<<A<<endl;
cout<<"B: "<<B<<endl;
是:
A: 0x6ffe40
B: 0x6ffe30
所以现在相差了 16 个字节,谁能解释为什么?为什么需要这个差距?当你像这样分配数组时,我不知道堆栈中存在间隙,并认为在这种情况下 B[1] 与 A[0] 相同。
C 和 C++ 都不保证自动变量在内存中的顺序,或者它们之间的任何填充。这些是您的特定编译器的实现细节。
为了解释您的实例中数组变量之间的间隙,您将需要研究 GNU C++ 编译器如何为变量分配内存。变量的分配取决于编译器。
变量之间存在差距的一些原因(不包括在内):
对齐
当处理器可以从与其字长对齐的地址中获取数据时,它们的效率会更高。例如,具有 32 位字的处理器喜欢从 4 字节对齐的地址中获取数据。从地址 5 访问 32 位将需要两次获取,然后进行一些字节移位以将字节按正确的顺序放置。
数据段
常量变量可以放在可执行文件或只读数据段中。它可以在 read/write 变量旁边声明,因此它们之间有一个间隙日志。
超限space
编译器可能会在数组后分配 space 以在数组溢出的情况下提供 "buffering"。
元信息
编译器可能会选择将有关数据类型的属性 (Meta) 信息放在数据类型之后(或之前)。例如,当为数组动态分配内存时,编译器可能会选择将分配的大小放在数组附近(对于回收内存很有用)。
注册
编译器可能会将变量放在寄存器中。因此变量会有不同的地址,因为寄存器通常不在同一个内存映射中;尽管有些处理器具有内存映射寄存器。
正在解析
变量可以分配在便于解析的位置。编译器可能会延迟变量分配,直到方便为止,或者在优化过程中可能会更改位置。