Use of MemoryFree library

I have executed this code:

#include <MemoryFree.h>

void setup(){

 Serial.begin(9600);

 for (int count = 0; count < 1; count++) {

 Serial.print("freeMemory()=");
 Serial.println(freeMemory());

 unsigned long a[400] = {0};

 Serial.print("freeMemory()=");
 Serial.println(freeMemory());

 }

 Serial.print("freeMemory()=");
 Serial.println(freeMemory());

}

void loop(){

 Serial.print("freeMemory()=");
 Serial.println(freeMemory());

}

Output:

freeMemory()=7976
freeMemory()=7976
freeMemory()=7976
freeMemory()=7976
freeMemory()=7976
freeMemory()=7976
....

I’m using a Mega2560 (it has 8K SRAM). When we enter into the loop, why the array a isn’t erased from memory?

This array consumes 4 x 400 = 1600 B. ¿Why we have 7976 B of memory free instead of 6592?

You're looking at it wrong. The array is never put in memory because the compiler sees it's not used and optimizes it away. You could easily see this if you comment out the array definition.

One technique for making sure this doesn't happen is to use the volatile keyword:

volatile unsigned long a[400] = {0};

That will force the compiler to not optimize it away.

You’re right. But in this other example the array a is used:

#include <MemoryFree.h>

void setup(){

	Serial.begin(9600);

	Serial.print("freeMemory()=");
	Serial.println(freeMemory());

	unsigned long a[400] = {0};

	Serial.print("freeMemory()=");
	Serial.println(freeMemory());

	a[0] = 25555555;

	Serial.println(a[0]);

	unsigned long b = a[0];

	Serial.print("freeMemory()=");
	Serial.println(freeMemory());

	Serial.println(a[0]);

	Serial.print("freeMemory()=");
	Serial.println(freeMemory());

}

void loop(){

	for (int count = 0; count < 1; count++) {

		Serial.print("freeMemory()=");
		Serial.println(freeMemory());

		unsigned long a[400] = {0};

		Serial.print("freeMemory()=");
		Serial.println(freeMemory());

	}

	Serial.print("freeMemory()=");
	Serial.println(freeMemory());

}

The output is the same. Why?

Isn't there something contradictory about wasting memory by using a library to see how much memory is available?

...R

Robin2: Isn't there something contradictory about wasting memory by using a library to see how much memory is available?

...R

I'm using it to see how the compiler works for latter optimize my original code (this it's a test code).

Robin2:
Isn’t there something contradictory about wasting memory by using a library to see how much memory is available?

MemoryFree reports free RAM.

The RAM footprint of the library is zero, its flash footprint negligible.

Kane12:
The output is the same. Why?

Because the compiler is pretty smart. Why should it use all that RAM when you don’t do anything with it?

I’ve found the MemoryFree library really useful for detecting memory leaks.

Hi,
Try this, I have filled the array with data using a UNO.

#include <MemoryFree.h>

void setup() {

  Serial.begin(9600);

  Serial.print("freeMemory()=");
  Serial.println(freeMemory());

  unsigned long a[400] = {0};

  Serial.print("freeMemory()=");
  Serial.println(freeMemory());
  for (int i = 0; i < 400; i = i + 1)
  {
    a[i] = 25555555;
  }
  Serial.println(a[0]);

  unsigned long b = a[0];

  Serial.print("freeMemory()=");
  Serial.println(freeMemory());

  Serial.println(a[0]);

  Serial.print("freeMemory()=");
  Serial.println(freeMemory());

}

void loop() {

  for (int count = 0; count < 1; count++) {

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    unsigned long a[400] = {0};

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

  }

  Serial.print("freeMemory()=");
  Serial.println(freeMemory());

}

and with or without the array I get

freeMemory = 1834

Tom… :slight_smile:

pert: Why should it use all that RAM when you don't do anything with it?

Which is the concept of using a variable? I'm showing its value through the serial port (Serial.println(a[0])) and I'm using it in an assignment (unsigned long b = a[0]). These questions are related with the fact that, due to the compiler, it seems that it's not always the same to declare a variable as global (the compiler doesn't optimize it) as to declare it inside a function (the compiler tries to optimize it) (speaking in memory terms).

Hi,
Try this code.
Run it with item 400 then item 100 and see the memory change.

Because memory allocation is done at compile time, the free memory is constant when the code is run.

#include <MemoryFree.h>
#define items 400
unsigned long a[items] = {0};
unsigned long Dummy;
int looper = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("In void setup");
  Serial.print("freeMemory()=");
  Serial.println(freeMemory());

  for (int i = 0; i < items; i = i + 1) //assigning some values
  {
    a[i] = 25555555;
  }

  Serial.println ("After assigning some values");
  Serial.print(items);
  Serial.println("\t items");
  Serial.print("freeMemory()=");
  Serial.println(freeMemory());
}

void loop()
{

  if (looper == 0)
  {
    Serial.println("In void loop");
    for (int i = 0; i < items; i = i + 1) // Using array
    {
      Dummy = (a[i]);
    }
    Serial.print("freeMemory()=");
    Serial.println(freeMemory());
    looper = 1;
    Serial.println("Test Complete");
  }

}

UNO
item 100 freemem = 1352
item 400 freemam = 152

Tom… :slight_smile:

Yes, you're right, but the reason is that this variable is a global variable and always is consuming SRAM (the compiler doesn't optimize it). My purpose is to define the minimum number of global variables. The real question is that I wanna know a technique to determine when a local variable will consume SRAM and when not.

Local variables (unless static) are stored on the stack. If the compiler doesn’t optimize them out, they occupy RAM from the time the function is called until it returns.

@gfvalvo

Arrays with zero elements are local variables without any RAM usage, but they have very rare legit uses, I see them more as typed address constants, not really as variables.

Ok. Look at this example:

char buffer[1000];
void setup(){}
void loop(){
--->Here we need to use the buffer.
callFunction();
}
void callFunction(){
--->Here we need to use the buffer.
}

In this example we don't need to keep the value of the buffer. We only need a char array[1000] within the loop and another into the function. This sketch consumes always 1000 bytes.

Another example:

void setup(){}
void loop(){
char buffer[1000];
--->Here we need to use the buffer.
callFunction();
}
void callFunction(){
char buffer[1000];
--->Here we need to use the buffer.
}

It's obvious that they are different variables. Because of this, when we go into the callFunction, we are consuming 2000 bytes? (and when we go out the function we consume 1000 bytes?)

I say this because in my code I'm in this situation. I have declared the buffer as global because only 1000 bytes are consumed (I prefer to always consume 1000 bytes instead of have a 2000 bytes peak of consume. I'm right?)

Whandall: Arrays with zero elements are local variables without any RAM usage, but they have very rare legit uses, I see them more as typed address constants, not really as variables.

So, they still go on the stack. They just happen to occupy 0 bytes of stack space ;D

Kane12: It's obvious that they are different variables. Because of this, when we go into the callFunction, we are consuming 2000 bytes? (and when we go out the function we consume 1000 bytes?)

I say this because in my code I'm in this situation. I have declared the buffer as global because only 1000 bytes are consumed (I prefer to always consume 1000 bytes instead of have a 2000 bytes peak of consume. I'm right?)

The behavior seems to be as expected. What is your question?

Whandall: Arrays with zero elements are local variables without any RAM usage

What are arrays with zero elements? Arrays that are created but they aren't used?

Kane12: What are arrays with zero elements? Arrays that are created but they aren't used?

int iUseNoMemory[0];

They occupy no memory, but have not much use, besides naming (via alias) a memory location, where something other will be placed. Which variable will be aliased is probably implementation dependent.

@Kane12,

Your examples in reply #13 server totally different purposes as the buffers are totally different buffers. The equivalent of example 2 that will not peak but always uses 2000 bytes.

char buffer1[1000];
char buffer2[1000];
void setup(){}
void loop(){
--->Here we need to use the buffer 1
callFunction();
}
void callFunction(){
--->Here we need to use the buffer 2
}

OK, and now imagine that you have 10 functions that all need a buffer. That means 10 arrays and you're out-of memory. So peaking is not a bad thing.

So now the real question is, do you want to share the buffer between the different functions? E.g. because loop() populates buffer and callFunction() processes the data in buffer.

sterretje: So now the real question is, do you want to share the buffer between the different functions? E.g. because loop() populates buffer and callFunction() processes the data in buffer.

In my case, in the loop the buffer is used for one purpose and in the function is used for another purpose. They are not related. In both cases, I only need 1000 bytes of memory. Because of this, I think that the global declaration of the buffer is the best solution.