0

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

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

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

   }
}

(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?

Brandon Kynoch
  • 150
  • 1
  • 1
  • 7
  • No. If the variable is actually being re-allocated during each iteration, then it's also being freed after each iteration -- whenever a variable with automatic storage duration goes out of scope, it's popped from the stack (or whatever underlying storage mechanism is responsible for automatic storage). My guess is that in certain special cases, the compiler can even reuse the same memory for the variable in each iteration rather than freeing it and reallocating it, depending on the variable's type. But that might be wrong. – Alexander Guyer Jun 30 '22 at 03:41
  • "the compiler can even reuse the same memory for the variable": Actually, I would expect that to be the *typical* behavior, not a special case. "Freeing and reallocation" would normally consist of nothing more than adding an offset to the stack pointer and subtracting it again, and the compiler should notice that these cancel and optimize them away. – Nate Eldredge Jun 30 '22 at 05:19

3 Answers3

3

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.

dbush
  • 205,898
  • 23
  • 218
  • 273
2

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 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. (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.35) If the scope is entered recursively, a new instance of the object is created each time. 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.
C 2011 Online Draft

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. 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.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

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.

please share the rest of the code for a clearer answer.

Sara Awwad
  • 40
  • 6