这个打印出两个变量地址的简单程序:
int main (int argc, char **argv)
{
float My_Float = 10.5;
char c;
printf("addr of My_float is %p\naddr of c is %p\n", &My_Float, &c);
}
如预期的输出:
addr of My_float is 0x7fff52a7eafc
addr of c is 0x7fff52a7eafb
然而,这个(唯一的区别是 char 数组而不是 char)对“c”有不同的地址。
int main (int argc, char **argv)
{
float My_Float = 10.5;
char c[20];
printf("addr of My_float is %p\naddr of c is %p\n", &My_Float, &c);
}
addr of My_float is 0x7fff5b922adc
addr of c is 0x7fff5b922af0
为什么 'c' 现在分配在不同的位置?更有趣的是,为什么 'c' 在 'My_Float' 之后分配,考虑到堆栈向下增长 - 我预计 'c' 的地址总是小于 'My_Float' 的地址,如第一个程序的情况。
我在配备 x86 处理器的 Mac 上运行 GCC。
最佳答案
作为Sourav Ghosh说,编译器可以自由地重新排序不在结构中的变量。发生这种情况的原因有很多:
- 内存对齐限制。从最受限制到最不受限制的顺序变量减少了内存中浪费的间隙。大多数数据类型都受限于它们可以从哪些地址开始。示例:字符可以是任何字符,短整数 (int16) 的地址通常必须是偶数。 int32 的地址通常必须能被 4 整除。指针往往属于最受限制的类别,这使得
char c
和char *ptr
之间存在很大差异。 - 如果程序有错误,编译器可能会下令减少常见问题。 Hans Passant解决了这个问题。 UB 是未定义的行为。
- 神秘的:通常与硬件行为或编译器编写者的优化或怪癖有关。
关于c - char 与 char 数组 : Why is there a difference? 的堆栈变量分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39195437/