Go Down

Topic: Free memory questions (Read 2 times) previous topic - next topic

Lima7

Hi,

I'm trying to save memory (RAM or data memory, not program memory) on a Mega2560, and I'm testing out some code I've found on this forum for displaying how much free memory is available. Firstly, here's the code I'm using....
.h file...
Code: [Select]
// memoryFree header
#ifndef MEMORY_FREE_H
#define MEMORY_FREE_H

#include "WProgram.h"     // needed for 'Serial'


#ifdef __cplusplus
extern "C" {
#endif

int freeMem();
int freeRam();
//void checkMem();

#ifdef  __cplusplus
}
#endif

#endif


.cpp file.....

Code: [Select]
#include "WProgram.h" 
#include "MemoryFree.h"

extern unsigned int __data_start;
extern unsigned int __data_end;
extern unsigned int __bss_start;
extern unsigned int __bss_end;
extern unsigned int __heap_start;
extern void *__brkval;


int freeMem()
{
  int free_memory;

  if((int)__brkval == 0)
     free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}


int freeRam()
{
  //int size = 1024; // Use 1034 with ATmega328
  //int size = 2048;  // Use 2048 with ATmega328 (Duemilanove)
  int size = 8192;  // Use 8192 with a Mega2560
  byte *buf;

  while ((buf = (byte *) malloc(--size)) == NULL);

  free(buf);

  return size;
}



Just to try to get some understanding of what's going on I've written some simple tests...
Code: [Select]
  Serial.print("Step 0. freeMem=<");Serial.print( freeMem() );Serial.print("> (bytes), freeRam=<");Serial.print( freeRam() );Serial.println("> (bytes)");
  char stringA[100+1];
  stringA[0]=0;
  for (int z=0;z<10;z++)
  {
    Serial.print("z=<");Serial.print(z);Serial.print(">, strlen()=<");Serial.print(strlen(stringA));Serial.print(">. freeMem=<");Serial.print( freeMem() );Serial.print("> (bytes), freeRam=<");Serial.print( freeRam() );Serial.println(">");
    strcat(stringA,"1234567890");
  }
 
  Serial.print("Step 1. freeMem=<");Serial.print( freeMem() );Serial.print("> (bytes), freeRam=<");Serial.print( freeRam() );Serial.println("> (bytes)");
  char stringB[100+1];
  stringB[0]=0;
  for (int z=0;z<10;z++)
  {
    Serial.print("z=<");Serial.print(z);Serial.print(">, strlen()=<");Serial.print(strlen(stringB));Serial.print(">. freeMem=<");Serial.print( freeMem() );Serial.print("> (bytes), freeRam=<");Serial.print( freeRam() );Serial.println(">");
    strcat(stringB,"1234567890");
  }

  Serial.print("Step 2. freeMem=<");Serial.print( freeMem() );Serial.print("> (bytes), freeRam=<");Serial.print( freeRam() );Serial.println("> (bytes)");
  char stringC[100+1];
  stringC[0]=0;
  for (int z=0;z<10;z++)
  {
    Serial.print("z=<");Serial.print(z);Serial.print(">, strlen()=<");Serial.print(strlen(stringC));Serial.print(">. freeMem=<");Serial.print( freeMem() );Serial.print("> (bytes), freeRam=<");Serial.print( freeRam() );Serial.println(">");
    strcat(stringC,"1234567890");
  }

Now, here's the issue. I'm expecting that each time I add a new string and then start increasing the length the amount of available memory will go down? But it doesn't , here's the results…

Quote
######################################################
Test 1......
######################################################
Step 0. freeMem=<5322> (bytes), freeRam=<5284> (bytes)
z=<0>, strlen()=<0>. freeMem=<36> (bytes), freeRam=<5284>
z=<1>, strlen()=<10>. freeMem=<36> (bytes), freeRam=<5284>
z=<2>, strlen()=<20>. freeMem=<36> (bytes), freeRam=<5284>
z=<3>, strlen()=<30>. freeMem=<36> (bytes), freeRam=<5284>
z=<4>, strlen()=<40>. freeMem=<36> (bytes), freeRam=<5284>
z=<5>, strlen()=<50>. freeMem=<36> (bytes), freeRam=<5284>
z=<6>, strlen()=<60>. freeMem=<36> (bytes), freeRam=<5284>
z=<7>, strlen()=<70>. freeMem=<36> (bytes), freeRam=<5284>
z=<8>, strlen()=<80>. freeMem=<36> (bytes), freeRam=<5284>
z=<9>, strlen()=<90>. freeMem=<36> (bytes), freeRam=<5284>
Step 1. freeMem=<36> (bytes), freeRam=<5284> (bytes)
z=<0>, strlen()=<0>. freeMem=<36> (bytes), freeRam=<5284>
z=<1>, strlen()=<10>. freeMem=<36> (bytes), freeRam=<5284>
z=<2>, strlen()=<20>. freeMem=<36> (bytes), freeRam=<5284>
z=<3>, strlen()=<30>. freeMem=<36> (bytes), freeRam=<5284>
z=<4>, strlen()=<40>. freeMem=<36> (bytes), freeRam=<5284>
z=<5>, strlen()=<50>. freeMem=<36> (bytes), freeRam=<5284>
z=<6>, strlen()=<60>. freeMem=<36> (bytes), freeRam=<5284>
z=<7>, strlen()=<70>. freeMem=<36> (bytes), freeRam=<5284>
z=<8>, strlen()=<80>. freeMem=<36> (bytes), freeRam=<5284>
z=<9>, strlen()=<90>. freeMem=<36> (bytes), freeRam=<5284>
Step 2. freeMem=<36> (bytes), freeRam=<5284> (bytes)
z=<0>, strlen()=<0>. freeMem=<36> (bytes), freeRam=<5284>
z=<1>, strlen()=<10>. freeMem=<36> (bytes), freeRam=<5284>
z=<2>, strlen()=<20>. freeMem=<36> (bytes), freeRam=<5284>
z=<3>, strlen()=<30>. freeMem=<36> (bytes), freeRam=<5284>
z=<4>, strlen()=<40>. freeMem=<36> (bytes), freeRam=<5284>
z=<5>, strlen()=<50>. freeMem=<36> (bytes), freeRam=<5284>
z=<6>, strlen()=<60>. freeMem=<36> (bytes), freeRam=<5284>
z=<7>, strlen()=<70>. freeMem=<36> (bytes), freeRam=<5284>
z=<8>, strlen()=<80>. freeMem=<36> (bytes), freeRam=<5284>
z=<9>, strlen()=<90>. freeMem=<36> (bytes), freeRam=<5284>
freeMem=<36> (bytes), freeRam=<5284> (bytes)


There are a number of issues with this.
Firstly, both functions are displaying totally different values
Secondly, both functions are displaying more-or-less unchanging values.

I guess either there's something wrong with my code (very possible) or there's something wrong in my understand of what I should be seeing.

Any suggestions?

Thanks

Mike

PaulS

Quote
I guess either there's something wrong with my code (very possible) or there's something wrong in my understand of what I should be seeing.

The location in the source code where the array is defined has no impact on the amount of space used when the code runs. The compiler sees all the array declarations, and allocates space for them, at compile time, not at run-time.

Putting your data in the array does not change the size of the array, so the amount of memory being used does not change.

Quote
Any suggestions?

Never stop learning.

Andy Brown

Quote

The location in the source code where the array is defined has no impact on the amount of space used when the code runs. The compiler sees all the array declarations, and allocates space for them, at compile time, not at run-time.


Only true for static/global declarations. The OP has declared his arrays on the stack which is allocated at run time on entry to the containing control block and de-allocated upon leaving. However the quantity of memory he's pushed on to the stack is bounded by the fixed array size and does not change during the tests. To see a change while in a loop he'll need to write a recursive function (grows the stack) or allocate heap memory (grows the heap).
Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Lima7

Ok, a couple of good points there, so what you're saying is that if I declare an array of size [100] then 100 bytes will be allocated to it (and hence un-available to anything else) even if only a few characters of the string are used?

I assume that memory is only allocated when that particular array/object is within scope? So in my example since all of the string are within scope all of the time the amount of free memory remains the same?

Finally, Any idea why the two functions give such different values?

thanks

PaulS

Quote
Only true for static/global declarations.

I was thinking in terms of the order of the print statements and the array declarations. The array is not allocated after the print occurs. I was not clear on that, but that was what I was trying to convey.

Go Up