I program embedded systems. One golden rule is that we never call malloc()
; all data must be statically allocated at compile time.
Hence, I am not really familiar with Variable Length Arrays, which were introduced with C99.
The concept seems clear enough, and I don't need it explaining. My question is what happens at run time if there isn't enough free memory for such an array?
I would imagine that it is o/s dependent, maybe compiler dependent, to what would GCC/Linux do, and MS visual Studio C on Windows? Any X99 or Posix definitions?
From the point of view of the Standard, an attempt to allocate a VLA with a size the implementation cannot accommodate invokes Undefined Behavior. Because the Standard provides no means of discovering what size array an implementation could safely create, and does not mandate that implementations allow any particular size, any attempt to create a VLA object with a size greater than 1 should be regarded as invoking Undefined Behavior except in cases where one happens to know enough about implementation's inner workings to determine the size of VLA it will be able to handle.
If malloc() is unavailable, one's best bet may be to define a large array of whatever type has the coarsest alignment requirement, store its address into a
volatile
-qualified pointer [the storage in which the pointer itself resides should be thus qualified] read it back, and interpret that as the start of a memory pool. No other use should be made of the original array object. While the Standard wouldn't guarantee that a compiler wouldn't decide that it should generate code that checks whether the pointer still identifies the original object and, if it does, skipping any code that would use that pointer to access anything other than the original object's type, the use ofvolatile
on the pointer should make that really unlikely.Once a memory pool is created, you can write your own memory-management functions to use it, though any time a pointer is returned to the pool it may be necessary to use the
volatile
-pointer-laundering hack to prevent compilers from using type-based aliasing to justify treating the last uses of storage as its old type as unsequenced relative to the first uses of storage as a new type.