变量声明是否意味着内存分配?

时间:2013-09-17 07:21:25

标签: c

中说出来是否准确
void f() {
    int x;
    ...
}

int x;”表示在堆栈上分配sizeof(int)个字节?

是否有任何规格?

5 个答案:

答案 0 :(得分:21)

标准中没有任何内容要求存在堆栈。标准中没有任何内容要求局部变量需要为其分配内存。变量可以放在寄存器中,甚至可以作为优化完全删除。

答案 1 :(得分:7)

没有关于此的说明,您的假设通常(但不总是)是假的。 考虑一些代码,如

void f() {
   int x;
   for (x=0; x<1000; x++) 
     { // do something with x 
     }
   // x is no more used here
}

首先,优化编译器会将x放在机器的某个寄存器中,而不会占用任何堆栈位置(除非您使用地址&x执行某些操作,例如将其存储在全局中)。 / p>

编译器也可以unroll that loop,并从生成的代码中删除x。例如,许多编译器将替换

for (x=0; x<5; x++) g(x);

相当于

g(0); g(1); g(2); g(3); g(4);

也许替换

for (x=0; x<10000; x++) t[x]=x;

类似

for (α = 0;  α < 10000;  α += 4) 
  { t[α] =  α; t[α+1] =  α+1; t[α+2] =  α+2; t[α+3] =  α+3; };

其中α是一个新变量(或者可能是x本身)。

此外,可能没有堆叠。对于C来说,它并不常见,但是其他一些语言没有任何堆栈(参见例如旧A.Appel的书使用continuation编译)。

顺便说一句,如果使用GCC,您可以检查其中间(Gimple)表示,例如MELT probe(或使用产生数百个转储文件的gcc -fdump-tree-all!)。

答案 2 :(得分:3)

来自GNU

3.2.1 C程序中的内存分配

  

声明自动变量时会发生自动分配   例如函数参数或局部变量。空间   当复合语句包含时,自动变量被分配   输入声明,并在复合声明时释放   退出了。在GNU C中,自动存储的大小可以是   表达方式各不相同在其他C实现中,它必须是a   恒定。

答案 3 :(得分:1)

这取决于很多因素。编译器可以优化并从堆栈中删除它,将值保持在寄存器中。等。

如果你在debug中编译它肯定会在堆栈中分配一些空间,但你永远不会知道。这没有指定。唯一指定的是变量的可见性以及变量的大小和算术。有关详细信息,请查看C99 spec

答案 4 :(得分:0)

我认为这取决于编译器。我为Code :: Blocks和Dev-C ++使用了默认的编译器,看起来初始化期间分配了内存。在下面的cout语句中,将n2更改为n1将给出相同的答案。但是,如果我将n1初始化为某个值,或者如果在显示平均值之前显示n2,则会得到不同的答案,这是垃圾。 请注意,由于变量未初始化,因此VS可以通过给出错误来正确处理此问题。

void getNums();
void getAverage();

int main()
{
    getNums();
    getAverage();

    return 0;
}
void getNums()
{
    int num1 = 4;
    double total = 10;
}
void getAverage()
{
    int counter;
    double n1 , n2;
    cout << n2/counter << endl;
}