c - char 与 char 数组 : Why is there a difference? 的堆栈变量分配

标签 c gcc

这个打印出两个变量地址的简单程序:

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 cchar *ptr 之间存在很大差异。
  • 如果程序有错误,编译器可能会下令减少常见问题。 Hans Passant解决了这个问题。 UB 是未定义的行为。
  • 神秘的:通常与硬件行为或编译器编写者的优化或怪癖有关。

关于c - char 与 char 数组 : Why is there a difference? 的堆栈变量分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39195437/

相关文章:

linux - gcc 链接目标文件和库 - 有什么区别?

c++ - OpenGL重启场景

C 数组结构声明

您能解释一下 fflush() 和重定向输出发生了什么吗?

c - C-如何将char数组传递给函数进行排序?

c++ - std::stoi 在 MinGW 上的 g++ 4.6.1 中不存在

c++ - 在库中使用 __gcov_flush 不会强制其他模块生成 .gcda 文件

c - Gtk:禁止 GtkWindow 的垂直调整大小

c++ - 视觉接受来自 std::byte 迭代器的 std::string

html - 寻找一种方法来排除 geninfo/genhtml 使用的文件