在c

时间:2016-11-10 19:07:15

标签: c memory types

#include<stdio.h>
int main()
{
    int a,b;
    float e;
    char f;
    printf("int &a = %u\n",&a);
    printf("int &b = %u\n",&b);
    printf("float &e = %u\n",&e);
    printf("char &f = %u\n",&f);
}

输出

int &a = 2293324
int &b = 2293320
float &e = 2293316
char &f = 2293315

但是当我使用这段代码并将printf替换为float -

#include<stdio.h>
int main()
{
    int a,b;
    float e;
    char f;
    printf("int &a = %u\n",&a);
    printf("int &b = %u\n",&b);
    printf("char &f = %u\n",&f);
}

然后输出

int &a = 2293324
int &b = 2293320
char &f = 2293319

此处地址未提供给float,但它在顶部声明。 我的问题是

  1. 内存未分配给程序中未使用的变量吗?
  2. 为什么地址按递减顺序分配。从2293324到2293320?

3 个答案:

答案 0 :(得分:4)

  

1)内存是否未分配给程序中未使用的变量?

是的,可以发生,允许编译器对其进行优化。

  

2)为什么地址按递减顺序分配。前2293324到2293320?

对于大多数本地存储实现而言,它通常使用CPU支持的堆栈指针,从堆栈顶部堆栈底部。所有这些局部变量最有可能在堆栈中分配。

答案 1 :(得分:2)

  

1)内存是否未分配给程序中未使用的变量?

这是一个允许的优化;如果未使用的变量不影响程序的可观察行为,编译器可能只是完全丢弃它。请注意,大多数现代编译器会警告您未使用的变量(因此您可以从代码中删除它们或使用它们执行某些操作)。

  

2)为什么地址按递减顺序分配。 ex-它从2293324到2293320?

编译器不需要以任何特定顺序为单独的对象分配存储空间,因此不要假设您的变量将按照它们声明的顺序进行分配。此外,请记住,在x86和其他一些系统上,堆栈“向下”向减少地址增长。请记住,任何堆栈的顶部只是最近推送某些内容的位置 - 它与相对地址值无关。

答案 2 :(得分:0)

虽然标准没有特别要求,但局部变量通常位于程序堆栈上。

当你输入一个函数时,首先要做的就是减少堆栈指针,为局部变量提供空间。

  SUBL #SOMETHING, SP

其中SOMETHING是所需的空间量,SP是堆栈指针寄存器。在你的第一个例子中,SOMETHING可能是13.然后地址:

  f is 0(SP)
  e is 1(sp)
  b is 5(sp)
  a is 9(sp)

我假设你的编译器没有对齐堆栈指针。通常他们会提供更多类似的东西:

  f is 3(SP)
  e is 4(sp)
  b is 8(sp)
  a is 12(sp)

在32位系统上,SOMETHING会被四舍五入为。

您可能希望使用编译器生成程序集列表,以查看其下的内容。

  

内存是否未分配给程序中未使用的变量?

请注意,对于本地变量,内存并未真正分配。变量临时绑定到程序堆栈上的某个位置(标准不需要堆栈,但在大多数情况下它是如何完成的)。这就是变量初始值未定义的原因。它本来可能与其他东西绑定。

编译器不需要为未使用的变量保留空间。它们可以被优化掉。通常,有一些编译器设置可以指示不要进行调试。

  

为什么地址按递减顺序分配。 ex-它从2293324到2293320?

程序堆栈通常会向下增长。从那天开始,程序将位于地址空间的底部,堆上方的堆和相反端的堆栈。

堆会朝着更高的地址增长。堆栈将朝向堆(较低地址)增长。

虽然地址空间可能比现在更复杂,但堆栈的下降仍然存在。

没有特别要求编译器按降序将变量映射到堆栈,但有50/50的可能性会以这种方式执行。