Dynamic Memory question (global vs local variables)

When compiling in the Arduino IDE, the user is notified as to the percent of dynamic memory used and the amount available for the specific hardware used. For example, when I declare a large global integer array the IDE reported that 70% of dynamic memory is used, but when I declared this array in a function (locally) the Arduino IDE reported that 0% of dynamic memory used.

I understand that when memory is defined locally (in function) it is disposed when out of scope. However, I don't understand the limitations of memory associated with locally defined variables. How do I know when the local variable memory size is too large for the board?

No that does not happen.

It is added on to the memory that the initial compile message told you you had left.

When the board starts behaving in a weird way. So always add the memory you are creating to see the total size of what you have left.

That is how micro controllers work, they are not PCs with operating systems.

For the details of this see:-

1 Like

So if I define a local array in a function, like:

int sample_total = 100000;
int16_t data[sample_total] = {};

and compile, the Arduino IDE outputs:

compile message:
Sketch uses 90480 bytes (1%) of program storage space. Maximum is 8384512 bytes.
Global variables use 11456 bytes (4%) of dynamic memory, leaving 250688 bytes for local variables. Maximum is 262144 bytes.

If I change sample_total = 1000;
then compile, the Arduino IDE outputs the exact statement as shown above.

Are we to use the 250688 bytes mentioned above and calculate the total local bytes required?

You also mentioned that I need to dispose of the Array once it's no longer needed by the local function, correct? I've not been able to find a demonstration of this. Can you advise me here.

No I didn't say that. I said that it doesn't happen automatically like you thought.
What Arduino are you using?

Absolutely no surprise at this, because it is complex and involves using pointers to shuffle memory about and update those pointers to the memory that you have not removed but moved to a new location and want to keep.

This is operating system stuff and memory management is simple not worth doing with the space you have in a micro controller.

Did you read that link?

Local variables are stored on the stack. They are "disposed of" automatically when the function exits. Nothing for you to do.

Very true, but you must have sufficient space on the stack in the first place to stop it crashing into the heap.

And of course you have to initialise the array all over again. And don't make the arrays static because then they consume memory just like global variables do.

This lack of awareness of this, is one of the things that trips up even experienced programmers, when they switch over to micro controllers, from micro, or even big, computers.

some will use both the stack and the heap

void sayHello() {
  String s = "Hello"; 
  s += " World, this string uses up a lot of memory in the heap, stack usage is not impacted by the length of this text.";
  Serial.println(s);
}

C++ ensures the destructor for the objects are called when the function exits.

The text above in the function will also eat up RAM on some Arduinos like the UNO (won't be in flash) so with the String you pay twice the cost !

I'm working with the RP2040 Chip. Thanks everyone for your help.

Thanks, that explains why there is such a large free memory. But the basic principles still apply, in a way that they wouldn't on a Raspberry Pi with its Linux operating system.

The down side of an operating system is it takes some time to boot up, as opposed to the instant on performance of a micro controller. And also it takes a command and time to shut it down, you just can't yank out the power supply.

You have different types of memory; SRAM, flash, EEPROM, etc. But to simplify, the bootloader, your code and libraries are stored in the flash, and the SRAM is used by your program in run time.

The compiler reports only what it knows at compiler time; flash and static allocated memory. Could also happen that if your code is not using a variable, the compiler optimizations just remove/ignore it.

Regarding the dynamic memory available for your program, it's organized is different areas. To simplify in general you have the heap and the stack.

The stack is where the local variables of a function and its parameters are stored. When you call a function from another, the vars of the current function remain on the stack and new ones plus the parameters are allocated on top. When you return back from the functions, you get its parameters from the stack in the correct order.
But, NOT everything used in a function goes to the stack. If you allocate memory directly it will go to the heap.

The Heap is a dynamic memory pool for global variables dynamically allocated memory, e.g. with malloc/free.
The heap is managed by the system, it grows automatically and can be fragemented when you allocate and deallocate a lot of memory banks.

Both memory areas reside in opposite sides of the memory and grow to the center.

In general what 'freeMemory' functions report is the free space between the stack and the heap, but not every free hole available inside the heap by deallocating memory.

To know what goes to the heap or to stack there are different rules, not always so obvious.

Because the compiler doesn't know what will happen at run time with that function. Maybe you never call it, or maybe you call it 1000 times recursively.

This array will go to the stack in run-time only when you call this function. So the compiler has no idea of it at compiler time.

You have to learn the rules in C/C++ of what is automatically allocated and deallocated and what you have to take care.
In general, what you allocate explicitly with malloc/new, you MUST deallocate yourself. Variables declared and allocated by the system/compiler will be automatically deallocated when you leave its scope. But it's not always so simple, you have to know and understand the allocation rules. Also make sure of not using allocated variables/arrays beyond its size.

This is the source of many of the mysterious crashes and odd behaviors of the programs.

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