-->
Page 1 of 1

Stack and heap memory - what is used where

PostPosted: Mon Sep 11, 2017 4:11 pm
by mamama1
Hi!

currently I'm working on a quite big project using a ESP8266.
So far I've managed to sort out many issues and I'm very happy at the moment because everything works like a charm :-)

However I was wondering, what takes up stack and what takes up heap space.
Somewhere I've read that global variables (that is, for me, variables defined outside of any function, right?) are in the heap and local variables (that is, for me, variables defined INSIDE of functions, right?).

is that true?

I'm wondering because I'm hitting the stack limit a bit and I'm having multiple large buffers defined within functions, all about 1000 to 3500 bytes large, maybe about 5 or 6 of them all together.

to avoid hitting the stack, I wanted to define one big buffer on the top of my ino file and use that buffer over and over from all of my functions.
however, when I did that, everything started to act weirdly, as if I had memory corruption somewhere or as if I was running out of memory.

Is that expected, am I missing something? Or should it work and I have to have a mistake in my code somewhere else?

Directions, please :-)

regards
mamama1

Re: Stack and heap memory - what is used where

PostPosted: Tue Sep 12, 2017 8:58 pm
by DTrain123
This image might give you a better idea of how the memory is used:
Image

The static memory is anything that is declared outside of a function. Or inside of a function with the static keyword.
Code: Select allchar buffer[5000];

void loop() {
    static char bufferTwo[20];
    ...
}

buffer and bufferTwo are both put in static memory when your program first starts running and will stay there as long as your program is running:

Heap memory is anything that is allocated with: malloc() realloc() calloc() or the 'new' keyword. This memory will stay allocated until it is unallocated with the: free() or 'delete' keyword.
In micro processors its usually best to avoid putting things on the heap unless you really have to, because it's easy to forget about deleting the memory afterwards and the heap will then grow until your program crashes.
Code: Select allvoid loop() {
    char *buffer = malloc(2000);
    char *bufferTwo = new char[50];
}

buffer and bufferTwo will be put in heap memory and will stay there until you call:
Code: Select all    free(buffer);
    delete [] bufferTwo;


Stack memory is all the other memory that is allocated inside of functions.
Code: Select allvoid loop() {
    char buffer[5000];
    char bufferTwo[20];
}

buffer and bufferTwo will be allocated on the stack when the loop() function runs and will be automatically cleaned up when the loop() function finishes running.

to avoid hitting the stack, I wanted to define one big buffer on the top of my ino file and use that buffer over and over from all of my functions.
however, when I did that, everything started to act weirdly, as if I had memory corruption somewhere or as if I was running out of memory.


What you talk about is possible to do, however you may run into problems if you have nested functions that both use the same buffer. The first function could fill the buffer with some data, then call the second function. The second function could then use the buffer to do it's work (overwriting whatever the first function put in the buffer) then when it goes back to the first function, the buffer has been changed. So it would look like the memory had been corrupted.