c中无限循环中的变量声明会导致堆栈溢出吗



这是一个简单的问题,但我只想把它扔出去,如果有人能验证我的理解是否正确或提供更多见解,我将不胜感激。如果这是重复的帖子,我提前道歉。

例如。在下面的代码中:

(1) stack_foverflow.c

int main() {
while (1) {
int some_int = 0;
char* some_pointer = some_function();
// ... some other code ....
}
}

(2) no_溢出.c

int main() {
int some_int;
char* some_pointer;
while (1) {
some_int = 0;
some_pointer = some_function();
// ... some other code ....
}
}

在第一个代码片段中,由于变量在无限循环中不断声明,这段代码最终会导致堆栈溢出,我说的对吗?(无限循环是有意的)

然而,在第二个代码片段中,我们实际上会重用内存的相同部分,这是所希望的结果,因为它会更高效。

编译器优化能够检测到这一点并防止堆栈溢出吗;优化级别是否可以实现这一点?

事实并非如此。

每次输入循环的主体时,都会在堆栈上创建两个变量。然后,当循环到达结束}时,这些变量被销毁。在测试循环条件并重新输入主体之后,将创建一对新的变量。

我说的在第一个代码片段中,由于变量在无限循环中不断声明,这段代码最终会导致堆栈溢出,这是对的吗?

否:

6.2.4对象的存储持续时间

6对于这样一个没有可变长度数组类型的对象,它的生存期从进入与其关联的块开始延长,直到该块的执行以任何方式结束。(输入一个封闭的块或调用一个函数会暂停但不会结束当前块的执行。)如果该块是递归输入的,则每次都会创建一个新的对象实例。对象的初始值不确定如果为对象指定了初始化,则每次在执行块时达到声明或复合文字时都会执行该初始化;否则,每次到达声明时,该值都会变得不确定

7对于这样一个具有可变长度数组类型的对象,其生存期从对象的声明开始延长,直到程序的执行离开声明的范围35)如果递归地输入范围,则每次都会创建对象的新实例。对象的初始值不确定。
35)离开包含声明的最里面的块,或者跳到该块中的一个点或声明之前的嵌入块,就离开了声明的范围
C 2011在线草案

每次通过循环,some_intsome_pointer的新实例都将在循环体的开始创建,并在循环体结束时销毁——无论如何,从逻辑上讲。在我使用过的大多数实现中,这些项的存储将在函数入口分配一次,并在函数出口释放。然而,这是一个实现细节,虽然它很常见,但你不应该依赖于它在任何地方都是真实的。

如果some_function动态分配内存或其他在循环结束前没有释放的资源,则可能会耗尽动态内存池或其他资源,但不应导致堆栈溢出。

通常不会,但这不是最佳实践。但是,如果some_function()在每次调用中都分配一个变量,并且它没有在同一个循环中释放,那么您将丢失已分配变量的位置,并出现内存错误。

请分享代码的其余部分以获得更清晰的答案。

相关内容

  • 没有找到相关文章

最新更新