对8位AVR微控制器进行编程我发现了一种行为 显示在此代码上:
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()按照中所述计算可用RAM http://jeelabs.org/2011/05/22/atmega-memory-use/。 当执行到达SomeClass :: start()时,我得到以下输出:
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
尽管在classA
内创建并销毁了while
个对象,但是
记忆似乎是在debugMethod()
的乞讨时分配的,并且仍然存在
直到方法结束。我希望内存只能在内部分配
同时,使用Free Ram: 2458
进行单色打印。
对正在发生的事情的任何解释?
有没有办法强制分配在while
内发生,没有
使用new
关键字?
使用的编译器:avr-gcc(WinAVR 20100110)4.3.3
答案 0 :(得分:4)
通常,整个函数的堆栈帧在函数的开头分配。
你可以试试gcc参数--param min-pretend-dynamic-size=100
它将尝试为超过100个字节的对象动态分配和释放堆栈[1]。
gcc可以使用-S
开关向您显示汇编代码,查看内容以了解正在发生的事情,以及--param min-pretend-dynamic-size是否会对您产生任何影响平台和功能。
在你的情况下,另一个解决方案是将while()循环的主体移动到一个新函数中,因为这将创建/销毁包含classA对象的堆栈帧。
[1] gcc docs:
<强>最小假装-动态尺寸强>
强制任何大小(以字节为单位)等于或大于的自动对象 比动态分配的指定值,就像它们的大小一样 不知道编译时间。这使他们的存储成为可能 在包含它们的块的末尾释放,减少总堆栈 如果多个使用重堆栈的函数被内联到a中,则使用 单一功能。它对合适的对象没有任何影响 用于分配寄存器(即,足够小和 没有他们的地址),也没有分配的对象 函数的最外面的块。默认值为零会导致其对象 在编译时已知大小以在函数处分配存储 条目。