C++ avr gcc上的自动解除分配
编程一个8位AVR微控制器我遇到一个行为 此代码中显示:C++ avr gcc上的自动解除分配,c++,memory,embedded,avr-gcc,C++,Memory,Embedded,Avr Gcc,编程一个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; };
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();
}
系统显示可用内存计算可用内存,如中所述
.
当执行到达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
尽管在while中创建并销毁了classA对象,但是
内存似乎是在debugMethod请求时分配的,并且仍然存在
直到方法结束。我希望内存只能在
然而,这样就有了一个带有空闲Ram的单色打印:2458
有什么解释吗
有没有一种方法可以强制分配在while内部进行,而不需要
使用新关键字
使用的编译器:avr gcc WinAVR 20100110 4.3.3通常,整个函数的堆栈帧在函数开始时分配。 您可以尝试gcc参数-param min假装动态大小=100 它将尝试为超过100字节的对象动态分配和取消分配堆栈[1] gcc可以通过-S开关向您显示汇编代码,查看该代码以了解到底发生了什么,以及-param min假装动态大小是否对您的平台和功能有任何影响 另一个解决方案是将while循环的主体移动到一个新函数中,因为这将创建/销毁包含classA对象的堆栈框架 [1] gcc文件: 最小动态大小 强制任何自动对象,其大小(字节)等于或大于 大于要动态分配的指定值,就像它们的大小一样 不知道编译时间。这使它们的存储空间更大 在包含它们的块末尾释放,减少总堆栈 如果将多个使用大量堆栈的函数内联到一个 单一功能。它不会对合适的对象产生任何影响 用于分配到寄存器,即足够小且 没有地址,也没有在 函数的最外层块。默认值为零,导致对象 编译时已知大小,以便在函数处分配存储 进入
通常,整个函数的堆栈帧在函数开始时分配。 您可以尝试gcc参数-param min假装动态大小=100 它将尝试为超过100字节的对象动态分配和取消分配堆栈[1] gcc可以通过-S开关向您显示汇编代码,查看该代码以了解到底发生了什么,以及-param min假装动态大小是否对您的平台和功能有任何影响 另一个解决方案是将while循环的主体移动到一个新函数中,因为这将创建/销毁包含classA对象的堆栈框架 [1] gcc文件: 最小动态大小 强制任何自动对象,其大小(字节)等于或大于 大于要动态分配的指定值,就像它们的大小一样 不知道编译时间。这使它们的存储空间更大 在包含它们的块末尾释放,减少总堆栈 如果将多个使用大量堆栈的函数内联到一个 单一功能。它不会对合适的对象产生任何影响 用于分配到寄存器,即足够小且 没有地址,也没有在 函数的最外层块。默认值为零,导致对象 编译时已知大小,以便在函数处分配存储 进入
你用优化编译了吗?可能是编译器将堆栈分配移动到debugMethod的开头作为优化。@Antti:是的,我使用-O1编译。我将使用-O0进行测试。@Antti:-O0也会发生同样的行为,所以这不是因为优化。您使用优化编译了吗?可能是编译器将堆栈分配移动到debugMethod的开头作为优化。@Antti:是的,我使用-O1编译。我将使用-O0进行测试。@Antti:-O0也会出现同样的行为,所以这不是因为优化。param min假装动态大小的想法非常好,在这个编译器上不接受:{ AVR GCC -MCMUC= ATMEGA1281-I.xC++-G-DFUCPU:1475656UL -O1-FSeN-Eng-壁- PARAM-MIN假装动态大小=100 IV0X05-IV0x05/包含,包括ILIB -MMD -MP-MF.DEP/ADC3.O.ADC3.CPP-O OBJ/Debug /ADC3.O o C++ c1PLUES.EXE:错误:无效参数“迷你预置动态-siz”是的,但不幸的是这个选项似乎只在一些较旧的gcc版本中可用,我在GCC4.x和更新的版本中找不到类似的选项,尽管您可以尝试-fconserve stackI已经尝试过了,但编译器也拒绝了这个选项。使用g++-Q-O1-help=优化器检查时,会显示行“-fconserve stack[disabled]”-对于-O2、-O3和-Os的结果相同。如果你有更多的想法,请告诉我。谢谢你的帮助!param min假装动态大小的想法非常简单
在这个编译器上不接受:{ AVR GCC -MCMUC= ATMEGA1281-I.xC++-G-DFUCPU:1475656UL -O1-FSeN-Eng-壁- PARAM-MIN假装动态大小=100 IV0X05-IV0x05/包含,包括ILIB -MMD -MP-MF.DEP/ADC3.O.ADC3.CPP-O OBJ/Debug /ADC3.O o C++ c1PLUES.EXE:错误:无效参数“迷你预置动态-siz”是的,好,但不幸这个选项似乎只在一些较旧的gcc版本中可用,我在GCC4.x和更新的版本中找不到类似的选项,尽管您可以尝试-fconserve stackI已经尝试过了,但编译器也拒绝了这个选项。使用g++-Q-O1-help=优化器检查时,会显示行“-fconserve stack[disabled]”-对于-O2、-O3和-Os的结果相同。如果你有更多的想法,请告诉我。谢谢你的帮助!