Will static variables fragment my SRAM?

I've been reading up about arduino SRAM memory.

Global variables get put in the "bottom" of the SRAM memory space at the microcontroller's startup, forming a heap, local variables then get created at the "top", as do notes for where to return to when a function finishes, growing downwards as a stack.

During operation only free spaces in memory above the heap and below the stack can be used for any further local variables (and/or return places for functions) as they become needed. A free space within the stack itself or within the heap itself is useless and cannot be accessed as free memory to put something new in to.

A static variable though is local in scope, but once it starts being used it somehow needs to be preserved throughout the time a program runs for. This would mean that when a static variable first appears, during the first time the function it exists within gets called, this static gets placed in to memory (either atop the heap? or at the botom of the stack?). But then when the function returns the static will still be there. And by being at such a location it will now lock away some proportion of the SRAM space below (if it uses heap) or above (if it uses stack) it.

Consider an example: a program starts, early on it calls a function with many local variables (a big array or something). This function then calls a second function. This is the first opportunity since the microcontroller was powered on at which this second function is being called. This second function contains static variables to be preserved for the next time the function is called. Now a static gets created atop the heap, above where that big array went. The second function does stuff. Now the second function exits. And then, after doing a few more things, the first function exits. Is it not the case that the first function can no longer set free the space it took up for the big array, because the second function has locked that stuff in to the heap by the second function adding a static to sit atop it? From here onwards the program runs with a massive lump of potential memory space locked away in the gap beneath the static variable? Once the static exists further uses of it might not fragment the SRAM any further, but one could have situations where a bunch of different statics in use end up taking up a vast amount of memory simply by "locking-in" below them many things which were local variables and should have been set free when various functions returned.

It would appear one can get fragmentation of the SRAM in any circumstances where SRAM can be getting deassigned in an order not precisely the reverse of how it was assigned. With normal functions and local variables you can only ever deassing precisely in reverse of how you assign (function 1 starts, creates variables, calls function 2, function 2 creates variables, finishes, frees func 2's variables func 1 resumes, finishes, frees func 1's variables, back to the initial state...) but a static appearing can surely complicte this, as it won't get released the way a local variale can be?

Is this logic correct, or is something done to handle statics more like global variables, and reserve a space in the bottom area of the SRAM (with all the normal globals) for them at the time the microcontroller starts up.

Thank you
P.S. I'm thinking in the context of AVR chips for now, but I guess the compiler treats statics the same way in this regard for all chip architectures anyway?

2 Likes

Nope. Globals and static are (typically) allocated in lower memory. That's not the heap. Function local variables are allocated on the stack that (typically) grows down from upper memory. The location of the "top" of the stack (actually in the lowest memory address of the stack area) is constantly changing as functions are called. The space in between the globals / static area and the stack is (more or less) available for the heap which is used for dynamic memory allocation.

1 Like

Memory Areas and Using malloc may be helpful for this discussion.

Static variables are treated as global variable, just not accessible outside of the defining function or class. They will be in the .data or .bss section and don't affect the heap or stack (other than the amount of storage taken). Don't worry about them.

1 Like

Thanks everyone. Knowing they're just like a global as far as memory usage goes is helpful.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.