views:

82

answers:

2

I was going through someone's code where I came across a thread:

while(TRUE)

{
 ......
 STRUCT_MSG_SYS_HEADER  sysHdr;
 .....
 ....
}

There are five threads like this, My point is that "STRUCT_MSG_SYS_HEADER sysHdr;" will lead to stackoverflow after some time or days... (Not tested though). So I decided to write a simple sample application

  1 #include "stdio.h"
  2
  3 struct infinite
  4 {
  5     int arr[1000000];
  6 }infinite;
  7
  8 int main()
  9 {
 10     while(1)
 11     {
 12         struct infinite infobj;
 13         printf("\ninfinite = %x\n", &infobj);
 14     }
 15     return 0;
 16 }

But here it is printing the same address for infobj. Is my thinking of stackoverflow is wrong or here compiler has done some optimization? (I consider myself good coder, but things like these force me to think again, read dennis richie again)

+4  A: 

The infobj is destroyed at the end of each iteration of while loop, hence stack is not overflowing and you are getting the same address again and again. Whether you can allocate int arr[1000000] on the stack depends on the maximum allowed stack size per thread. On VC compiler this is 1 MB but can be changed through compiler options.

Naveen
that means my assumption for "STRUCT_MSG_SYS_HEADER sysHdr" stackoverflow is wrong?
alam
@alam: Yes, the object is destroyed at the end of the loop. So the stack doesn't grow for each iteration of the loop. Hence you won't have stackoverflow.
Naveen
+1 for the precise answer!
KMan
If I change a code bit from stack allocation to heap allocation. for e.g. struct infinite *infobj = (struct infinite *) malloc (sizeof (struct infinite)); ... then will there be any memory leaks? (My guess NO: same memory will be allocated again and again)
alam
@alam: there will be memory leak. You are missing the point. The memory for the *pointer* will be allocated from stack, but the memory it is *pointing* is allocated from *heap*. The memory for the *pointer* will be released automatically at the end of loop but the memory it is *pointing* is still not released resulting in memory leak. You need to explictly `free` the memory so that the memory allocated on heap is released.
Naveen
+4  A: 

No stack overflow will occur. That stack-allocated variable will only live for the duration of the loop iteration and after that stack space it occupies can be reused. Typically when the next iteration starts exactly the same space will be used for the variable in the new iteration.

Stack overflow could occur in case of deep recursive chain of calls of the same function because when the new call would start all the variables in the scope of the previous call would need to be retained, so the sapce would not be reused, but instead more stack space would be used for each new call. This is not the case in this question.

sharptooth
I'd add - there is guarantee that compiler will place `infobj` on stack, it is up to compiler where to place automatic variables.
qrdl
@qrdl: Actually there's no guarantee there is a stack - that's an implementation detail. The key here is the variable lifetime - since it ends so early space can be reused.
sharptooth
@sharptoon That's exactly what I wanted to write - the word "no" in front of "guarantee" somehow escaped.
qrdl
If I change a code bit from stack allocation to heap allocation. for e.g. struct infinite *infobj = (struct infinite *) malloc (sizeof (struct infinite)); ... then will there be any memory leaks? (My guess NO: same memory will be allocated again and again)
alam
@alam: Definitely there will be memory leaks if you don't `free()` that memory later. When you `malloc()` memory it is marked as yours and no sunsequent `malloc()` calls will return that memory until you explicitly `free()` it.
sharptooth