If I define an array in an if statement, then is memory allocated?

If I define an array in an if statement, then memory is allocated at compile time, for example.

if(1) { int a[1000]; } else { float b[1000]; } 

Then 2 * 1000 memory is allocated for ints + 4 * 1000 for float?

+7
c arrays memory
source share
5 answers

It is reserved on the stack at runtime (assuming a nontrivial condition - in your case, the compiler will simply exclude the else part). This means that it exists only within the scope block (between {} ).

+4
source share

In your example, only memory for ints (1000 * sizeof (int)) is allocated on the stack.

As you can guess, this happens at runtime. The generated code has instructions for allocating space on the stack when the appropriate code block is entered.

Keep in mind that this is due to the semantics of the language. The structural structure introduces a new scope, and any automatic variables allocated in this area have a lifespan that lasts as long as the scope. In C, this is realized by allocating it on the stack, which is discarded when the region disappears.

Just in order to drive home, note that the distribution would be different if the variables were of a different nature.

 if(1) { static int a[1000]; } else { static float b[1000]; } 

In this case, space is allocated for both int and float. The lifetime of these variables is a program. But visibility is within the block area into which they are allocated.

+1
source share

Region

Variables declared inside the scope of the { } pair are on the stack. This applies to variables declared at the beginning of a function or any pair { } inside a function.

 int myfunc() { int i = 0; // On the stack, scoped: myfunc printf("%i\n"); if (1) { int j = 1; // On the stack, scope: this if statement printf("%i %i\n",i,j); } printf("%i %i\n",i,j); // Won't work, no j } 

Currently, the scope of variables is limited to the surrounding { } . I remember that some old Microsoft compilers did not limit the scope, and that in the example above, the final printf() will compile.

So where is it in memory?

Memory i and j simply reserved on the stack. This is not the same as allocating memory with malloc() . This is important because the call to malloc() very slow in comparison. Also with dynamic memory allocation using malloc() you should call free() .

In fact, the compiler knows in advance what space is needed for the function variables, and will generate code that refers to the memory as to what the stack pointer is when calling myfunc() . As long as the stack is large enough (usually 2 MB, OS dependent), all is well.

A stack overflow occurs in a situation where myfunc() is called with a stack pointer already close to the end of the stack (i.e. myfunc() is called by a function that in turn was called by another, which it itself called another, etc. Each layer of nested function calls moves the stack pointer a bit more and returns only when functions return).

If the space between the stack pointer and the end of the stack is not large enough to hold all the variables declared in myfunc() , the code for myfunc() will simply try to use locations outside the stack. This is almost always bad, and exactly how bad and how hard it is to notice that something went wrong depends on the operating system. On small embedded microcontrollers, this can be a nightmare, as this usually means that some other part of the program data (for example, global variables) is silently overwritten, and it can be very difficult to debug. On large systems (Linux, Windows), the OS will tell you what happened, or just make the stack bigger.

performance considerations

In the above example, I assign the values i and j . It actually takes a small amount of runtime. j assigned 1 only after evaluating the if statement and the subsequent branch, where j declared.

Say, for example, the if statement was not evaluated as true; in this case, j never assigned 1. If j was declared at the beginning of myfunc() , then it was always assigned the value 1 regardless of whether the if statement was true - a small waste of time. But consider a less trivial example when a large array is declared initialized; which will take longer to complete.

 int myfunc() { int i = 0; // On the stack, scoped: myfunc int k[10000] = {0} // On the stack, scoped: myfunc. A complete waste of time // when the if statement evaluates to false. printf("%i\n"); if (0) { int j = 1; // On the stack, scope: this if statement // It would be better to move the declaration of k to here // so that it is initialised only when the if evaluates to true. printf("%i %i %i\n",i,j,k[500]); } printf("%i %i\n",i,j); // Won't work, no j } 

Placing the declaration of k at the top of myfunc() means that a 10000 long loop is executed to initialize k every time myfunc() called. However, it is never used, so a cycle is a waste of time.

Of course, in these trivial examples, compilers optimize unnecessary code, etc. In real code, where the compiler cannot predict in advance what the execution flow will be, everything remains in place.

+1
source share

As DCoder and paddy corrected me, the memory will be computed at compile time, but allocated at runtime in the stack's memory segment, but with the volume and lifetime of the block in which the array is defined. The size of the allocated memory depends on the size of int and float in your system. Read this for a review on memory card C

0
source share

The memory for the array in the if block will be allocated on the stack at runtime. else part will be optimized (deleted) by the compiler. For more information on where variables will be allocated, see Segmentation Error When Writing to a String

0
source share

All Articles