Question about the life and memory space of a variable inside a function...

Hello everybody, sorry for my english.

I will try to explain you what Im thinking about.

Im programming like yours and while Im programming, Im trying to save Arduino memory bytes.

The question is... the variables that are defined inside a function, after the function finishes its work, this memory space used by the function variables, is free for new variables of the system or other functions or is it not available space to be used ?

Im worried about this, because the goal is avoid system crashes.

Best regards, Ginza.

After the function has finished, that memory becomes available again.
Global variables stay in memory, but variables on the stack are temporary.

int temperature;        // global variable

void Test()
{
  int x;          // temporary variable on the stack.
}

The compiler can do optimization tricks with code and variables. The compiler might keep a variable in the registers and not even use any memory for it.

When you have a Arduino Uno board and you run out of memory, you can buy the Arduino Mega 2560.
Normally the Arduino Uno should have enough memory for Serial communication, for sensors, for LCD display and so on. If you need large buffers of data or if you use an Ethernet Shield with the Uno, then the Uno might run out of memory.

The SRAM you have is a very scarce resource. When you define a global or static variable, it is allocated on what is called the heap. Global and static variables exist throughout the run of the program. Arguments that are passed to a function are allocated on the stack. The stack space starts at the top of SRAM and grows downward while the heap starts at low memory and grow upward. If the two ever meet you get an out-of-memory message. That said, the stack memory that was used for arguments that were passed to the function is reclaimed when program control leaves the function. Therefore the stack ebbs and flows as the program runs, depending upon the way you wrote your program. If you have nested functions--functions within functions that call other functions--the stack keeps getting deeper and deeper since it cannot reclaim the memory until the code starts to "unwind" itself. Therefore, you want to think about the depth of nested function calls.

Perhaps this diagram will help:

Thanks Peter_n and econjack for your replies.

So, local variables are better than global ?

I use both of them, but I thinked that a global variable already reserve memory for it and the local variable of a function is searching memory space each time that is called the function.

Im trying to avoid String variables and using char arrays. Only one function has got a String variable and is because I dont know how to convert a integer value to the char array without using a String variable.

For example:

   char array[1] = {'\0'};   
   int num = 5;   
   String str;
    
   str = String(num);     
   str.toCharArray(array, 1);

I dont like this method because I had to declare a String variable, but is the only way that I have now. Perhaps you have a better idea about this.

You have an array that can hold one character. You tell the toCharArray() method that the array can hold one character. So, the String class is going to put 0 characters plus the terminating NULL in that array. Rather useless, eh?

I dont know how to convert a integer value to the char array

itoa() doesn't piss away all the resources that the String class does.

Hi Pauls, thanks for you reply.

Was only an example...not really practical.

I have read about itoa(), I will try to use it.

About itoa() ...when I call it inside a function, the memory used by itoa() is free after the function finish ?

Another question, I know that each skecth is diferent, but how many minimum dynamic memory must be free to avoid system crashes ?

Best regards, Ginza.

There really isn't any "searching" going on for variables allocated on the stack. There's a stack pointer that is maintained in the code so it know where the Top Of Stack (TOS) always is located. It's a simple task to allocate memory from the TOS and release it when done.

I prefer local to global variables not because of the memory issues, but rather because local variables are "invisible" outside the function in which they are defined (i.e., the concept of scope). If something goes wrong with a variable, at least I know it's inside the function where it is defined. With global variables, it could be anywhere from its point of definition to the end of the source code file...much harder to debug.

You are wise to dump the String class. They are a little easier to use, perhaps, but they are resource hogs. Take Paul's advice and use itoa() to convert a string to an int.

Hi econjack, about the TOS...is posible know the position of it before the system crash and reset the system ?

Im thinking about restart all the system and avoid a system freezing.

Best regards, Ginza.

Hi econjack, about the TOS...is posible know the position of it before the system crash and reset the system ?

Why would it matter? The top of the stack will be different after a reset.

Im thinking about restart all the system and avoid a system freezing.

99.999999999% of the time, the problem is your code. Fix it, and watchdog timers and software resets are not necessary.

In fact, as we discovered in another recent thread, local variables may be allocated to processor registers, and therefore take no memory at all.

I am curious, what would leave 'holes' in the heap?

Like on the image above:

If I do something like this:

Object myObject = new Object(); // global variable
...
// then somewhere in the loop:
myObject = NULL;
..
// will this create a 'hole' on the heap?

If I do something like this:

Setting the value to NULL is not what causes holes in memory. Abandoning an object, without invoking its destructor can render memory unavailable for other uses.

The holes happen when you allocate space for a one character String, then add a character to it. That results in allocating two bytes, copying the one that was in the String, and adding the new one. The one byte allocation is freed, and available to be reused, but how often do you need to allocate one byte? That tiny amount of memory is a hole.

Now, you add another character, so three bytes are allocated, and the two byte allocation freed. Those two bytes may, or may not, be adjacent to the one byte that was freed earlier. If so, there are now three contiguous bytes available. If not, you have two holes.

Then, 4 bytes, 5 bytes, 6 bytes, etc. and you may have little holes all over the place.

Thanks for the explanation, I understand it now.

Object myObject = new Object(); // global variable
...
// then somewhere in the loop:
myObject = NULL;

The inverse of "new" is "delete".

Thus:

Object myObject = new Object(); // global variable
...
// then somewhere in the loop:
delete myObject;

Got it, thanks!

Hi everybody...I have read your messages and I start to think about...Is posible reorganize the memory to delete the memory holes ?

About your last message Nick, Is better destroy the functions variables before leave the function that create them or they will be destroyed when the function finish its work ?

Just try to use local variables instead of globals, also avoid Strings.

When you initialize a variable inside a function - it will be allocated on the stack, and automatically cleared up when the function exits. So no need to destroy anything.

No, the arduino has no garbage collection, and you have no access to this. If you got really chummy with the malloc()/free() system you might be able to, but it is probably not worth the bugs it would cause.

Hey great discussion, very informative for me as a newbe to embedded programming
Thanks

Ok, one more question about improve memory management, inside a function, String cast is the same like define a String variable ?

Best regards Ginza.