Programming a 8-bit AVR microcontroller I’ve came across a behavior that is
shown on this code:
class classA
{
public:
classA(Display *d) : _d(d) { _d->println("classA()", 0); }
~classA() { _d->println("~classA()", 1); }
uint8_t array[200];
Display *_d;
};
void useClassA(classA *a)
{
a->array[3] = 5;
}
void SomeClass::start()
{
SYSTEM_DISPLAY_FREE_RAM();
debugMethod();
_ui->lcd().println("after debugMethod", 3);
SYSTEM_WAIT_DEBUG_BUTTON();
SYSTEM_DISPLAY_FREE_RAM();
}
void SomeClass::debugMethod()
{
_ui->lcd().println("entered debugMethod", 3);
SYSTEM_WAIT_DEBUG_BUTTON();
SYSTEM_DISPLAY_FREE_RAM();
_ui->lcd().println("before while", 3);
SYSTEM_WAIT_DEBUG_BUTTON();
volatile uint8_t i = 1;
while (i != 0)
{
classA cA(&_ui->lcd());
SYSTEM_DISPLAY_FREE_RAM();
cA.array[199] = i--;
useClassA(&cA);
}
_ui->lcd().println("after while", 3);
SYSTEM_WAIT_DEBUG_BUTTON();
SYSTEM_DISPLAY_FREE_RAM();
}
SYSTEM_DISPLAY_FREE_RAM() calculates available RAM as described in
http://jeelabs.org/2011/05/22/atmega-memory-use/.
When execution reaches SomeClass::start() I got the following output:
Free Ram: 2677
entered debugMethod
Free Ram: 2458
before while
classA()
Free Ram: 2458
~classA()
after while
Free Ram: 2458
after debugMethod
Free Ram: 2677
Despite classA object is created and destructed inside the while, the
memory seems to be allocated at the begging of debugMethod(), and remains
until the method ends. I expected memory to be allocated only inside of the
while, thus having a sigle print with Free Ram: 2458.
Any explanations of what is going on?
Is there a way to force the allocation to happen inside the while, without
using new keyword?
Compiler used: avr-gcc (WinAVR 20100110) 4.3.3
Typically the stack frame for the whole function is allocated at the start of the function.
You can try the gcc argument
--param min-pretend-dynamic-size=100which will try to dynamically allocate and deallocate stack for objects over 100 bytes [1].
gcc can show you the assembly code with the
-Sswitch, look at that to see under the hood on what’s going on, and whether the –param min-pretend-dynamic-size had any effect on your platform and function.Another solution in your case would be to move the body of your while() loop into a new function, as that would create/destroy the stack frame containing the classA object.
[1] gcc docs:
min-pretend-dynamic-size