After removing all the calls to malloc and calloc from our code for an embedded system, I was surprised to find that malloc was still being linked in. The call graph pointed me to a function which had no explicit *alloc calls, and no calls to any library functions that might allocate, like strdup
.
I had to look at the generated assembly to realize that it was due to an inlined function which contained a VLA.
I thought VLAs had to be stack-allocated. Is this compiler broken?
C language provides the alloca function to allocate arbitrary size array on the stack. After the function returns or the scope ends, the stack memory is automatically reclaimed back (popped back) without the developer having to deallocate it explicitly and thereafter is unsafe to access it again from another function.
The allocation and deallocation for stack memory is automatically done. The variables allocated on the stack are called stack variables, or automatic variables. Since the stack memory of a function gets deallocated after the function returns, there is no guarantee that the value stored in those area will stay the same.
In Java reference types are stored in the Heap area. As arrays are also reference types, (they can be created using the “new” keyword) they are also stored in the Heap area.
Variable length arrays is a feature where we can allocate an auto array (on stack) of variable size. It can be used in a typedef statement. C supports variable sized arrays from C99 standard. For example, the below program compiles and runs fine in C.
There is no requirement that VLAs be allocated from the stack (the language standard doesn't even mention stacks or heaps). The only requirement is as follows:
6.2.4 Storage durations of objects
...
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.
Given this, it makes sense to allocate from the stack, but for very large objects this may not be possible, and such an object may be allocated from the heap or some other memory segment instead. The bookkeeping is up to the implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With