在下面的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
}
答案 0 :(得分:5)
调用函数时,它将在堆栈上分配一次。在性能方面,两种方式之间没有区别(但回想一下,在循环之后,y
仍将在范围内)。变量似乎在每次迭代之间被创建和销毁(因此它在迭代之间“丢失”它的值)是由编译器创建的行为;实际的内存位置始终是相同的。
答案 1 :(得分:3)
每次都没有分配,但每次迭代都会分配一个新值。循环在一个方法中,该方法有自己的堆栈帧。变量y在该堆栈帧中分配。
答案 2 :(得分:0)
为循环中的每个回合创建一个新变量。
但是,对于int
类型变量并不重要。最好为变量设置一个小范围。并且编译器可能足够聪明,每次都可以重用相同的空间。
答案 3 :(得分:0)
我认为每次进入循环时,变量y都将在堆栈上进行分配,因为变量在离开此范围时将被取消定位。
答案 4 :(得分:0)
它不能等同于您提供的那个,因为y
将超出for
循环的范围。
但这一切都取决于编译器,你必须衡量两者之间的表现,如果那是你想要的。
答案 5 :(得分:0)
代码中的y
是一个局部变量。尽管许多人认为这些都没有分配。它们可能会也可能不会在堆栈上为它们保留一些空间,但只有在优化之后才能确保它们的地址被占用。
在所有其他情况下,它们可能根本没有在堆栈上保留空间。或者他们使用的堆栈上可能有一些空间,但是同一个空间被重用于多个变量,甚至在某些情况下,用于将参数传递给您正在调用的函数。
当在堆栈上保留空间(可能会或可能不会发生)时,通常在函数输入时保留空间。但是这是一个实现细节。这样做是因为它是最快的方式。没有要求它以这种方式完成,并且实现可以很好地动态地改变当前堆栈帧的大小(在大多数现代处理器上,这是一个愚蠢的事情,但是这样的实现仍然是正确的。)
答案 6 :(得分: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;
}