简体   繁体   English

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

[英]Will variable declaration inside infinite loop in c cause stack overflow

This is a simple question, but I would just like to throw this out there and appreciate if anyone could validate if my understanding is correct or provide some more insight.这是一个简单的问题,但我只想把它扔在那里,并感谢是否有人可以验证我的理解是否正确或提供更多见解。 My apologies in advance if this is a duplicate post.如果这是重复的帖子,我提前道歉。

Eg.例如。 In the code below:在下面的代码中:

(1) stack_overflow.c (1) stack_overflow.c

int main() {
   while (1) {
      int some_int = 0;
      char* some_pointer = some_function();

      // ... some other code ....

   }
}

(2) no_overflow.c (2) no_overflow.c

int main() {
   int some_int;
   char* some_pointer;

   while (1) {
      some_int = 0;
      some_pointer = some_function();

      // ... some other code ....

   }
}

Am I correct in saying that in the 1st code snippet, this code would eventually cause a stack overflow because of the variables continually being declared inside of the infinite loop?我是否正确地说在第一个代码片段中,由于在无限循环中不断声明变量,此代码最终会导致堆栈溢出? (The infinite loop is intentional) (无限循环是故意的)

Whereas, in the second code snippet we would actually be reusing the same parts of memory, which is the desired outcome as it would be more efficient.然而,在第二个代码片段中,我们实际上将重用内存的相同部分,这是期望的结果,因为它会更有效。

Would compiler optimisation be able to detect this and prevent the stack overflow, if so which c compilers & optimisation levels would achieve this?编译器优化是否能够检测到这一点并防止堆栈溢出,如果可以,哪些 c 编译器和优化级别可以实现这一点?

This is not the case.不是这种情况。

Each time the body of the loop is entered, two variables are created on the stack.每次进入循环体时,都会在堆栈上创建两个变量。 Those variables are then destroyed when the loop hits the ending } .当循环到达结尾}时,这些变量就会被销毁。 After the loop condition is tested and the body is reentered, a new pair of variables are created.在测试循环条件并重新输入主体后,会创建一对新的变量。

Am I correct in saying that in the 1st code snippet, this code would eventually cause a stack overflow because of the variables continually being declared inside of the infinite loop?我是否正确地说在第一个代码片段中,由于在无限循环中不断声明变量,此代码最终会导致堆栈溢出?

No:不:

6.2.4 Storage durations of objects 6.2.4 对象的存储期限
... ...
6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way . 6 对于这种不具有可变长度数组类型的对象,它的生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束 (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. (进入封闭的块或调用函数会暂停,但不会结束当前块的执行。)如果递归地进入块,则每次都会创建对象的新实例。 The initial value of the object is indeterminate. 对象的初始值是不确定的。 If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; 如果为对象指定了初始化,则在执行块时每次到达声明或复合文字时都会执行它; otherwise, the value becomes indeterminate each time the declaration is reached . 否则,每次达到声明时,值都会变得不确定

7 For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration. 7 对于这种具有可变长度数组类型的对象,它的生命周期从对象的声明开始,直到程序的执行离开声明的范围。 35) If the scope is entered recursively, a new instance of the object is created each time. 35)如果递归进入范围,则每次都会创建一个新的对象实例。 The initial value of the object is indeterminate. 对象的初始值是不确定的。
35) Leaving the innermost block containing the declaration, or jumping to a point in that block or an embedded block prior to the declaration, leaves the scope of the declaration. 35) 离开包含声明的最里面的块,或跳转到该块中的某个点或声明之前的嵌入块,离开声明的范围。
C 2011 Online Draft C 2011 在线草案

Each time through the loop new instances of some_int and some_pointer will be created at the beginning of the loop body and destroyed at the end of it - logically speaking, anyway.每次循环时, some_intsome_pointer的新实例都将在循环体的开头创建并在循环体结束时销毁 - 从逻辑上讲,无论如何。 On most implementations I've used, storage for those items will be allocated once at function entry and released at function exit.在我使用的大多数实现中,这些项目的存储将在函数入口处分配一次,并在函数出口处释放。 However, that's an implementation detail, and while it's common you shouldn't rely on it being true everywhere.然而,这是一个实现细节,虽然它很常见,但您不应该依赖它在任何地方都是正确的。

If some_function dynamically allocates memory or some other resource that doesn't get freed before the end of the loop you could exhaust your dynamic memory pool or whatever, but it shouldn't cause a stack overflow as such.如果some_function动态分配内存或其他一些在循环结束之前没有被释放的资源,你可能会耗尽你的动​​态内存池或其他什么,但它不应该导致堆栈溢出。

normally no but it's not the best practice.通常没有,但这不是最佳做法。 however, if some_function() is allocating a variable with every call, and it's not being freed in the same loop, you will lose the location of your allocated variable and have memory errors.但是,如果some_function()每次调用都分配一个变量,并且它没有在同一个循环中被释放,那么您将丢失分配变量的位置并出现内存错误。

please share the rest of the code for a clearer answer.请分享其余代码以获得更清晰的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM