9

在以下 C++ 代码中:

    for (int i=0; i<10; i++)
    {
        int y = someFunctionCall();

        //Some statements
    }

变量 (y) 是在每次循环迭代时分配,然后在迭代完成时释放,还是为所有循环迭代分配一次?

上述代码是否等同于以下代码?:

    int y;
    for (int i=0;i<10;i++)
    {
        y = someFunctionCall();

        //Some statements
    }
4

7 回答 7

6

当函数被调用时,它将在堆栈上分配一次。在性能方面,这两种方式之间没有区别(但请记住,最后一种方式,y在循环之后仍然在范围内)。变量似乎在每次迭代之间被创建和销毁(因此它在迭代之间“丢失”其值)是由编译器创建的行为;实际的内存位置始终相同。

于 2012-09-16T11:48:33.097 回答
3

它不是每次都分配的,而是在每次迭代中分配一个新值。循环在一个方法中,该方法有自己的堆栈帧。变量 y 在该堆栈帧中分配。

于 2012-09-16T11:50:49.457 回答
1

循环中的每一轮都会创建一个新变量。

但是,对于int不重要的类型变量。最好为变量设置一个较小的范围。而且编译器可能足够聪明,每次都可以重用相同的空间。

于 2012-09-16T11:48:32.893 回答
0

我认为每次进入循环时变量 y 都会在堆栈上分配,因为变量在离开此范围时将被释放。

于 2012-09-16T11:49:58.473 回答
0

它不能等同于您提出的那个,因为y它超出了for循环的范围。

但这一切都取决于编译器,如果这是你所追求的,你必须测量两者之间的性能。

于 2012-09-16T11:52:26.500 回答
0

您的y代码中的 是一个局部变量。尽管许多人认为这些没有分配。它们可能会或可能不会在堆栈上为它们保留一些空间,但只有在优化后,它们的地址被占用时才能保证发生这种情况。

在所有其他情况下,它们可能根本没有在堆栈上保留空间。或者他们使用的堆栈上可能有一些空间,但是相同的空间被重复用于多个变量,甚至在某些情况下,用于将参数传递给您正在调用的函数。

当在堆栈上保留空间时(可能会或可能不会发生),通常会在函数进入时立即保留所有空间。然而,这是一个实现细节。这样做是因为它是最快的方法。不需要以这种方式完成,并且实现可以很好地动态更改当前堆栈帧的大小(在大多数现代处理器上,这样做是愚蠢的,但这样的实现仍然是正确的)。

于 2012-09-16T12:06:40.037 回答
0

对于内置类型,它并不重要(无论可见性范围如何)。对于对象,对象变量是否留在/退出 for 循环确实(!)很重要。考虑以下:

#include <iostream>

struct A
{

  static int i;
  void * a;

  A() : a(this) { ++i; }

};

int A::i = 0;

int main()
{

    for (int i = 0; i != 10; ++i)
    {

      A a;

      std::cout << a.a << " | " << a.i << std::endl;

    }

    return 0;
}
于 2015-06-25T15:21:05.727 回答