avr-gcc上的自动释放

时间:2012-08-30 13:31:45

标签: 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;
  };
  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

1 个答案:

答案 0 :(得分:4)

通常,整个函数的堆栈帧在函数的开头分配。 你可以试试gcc参数--param min-pretend-dynamic-size=100 它将尝试为超过100个字节的对象动态分配和释放堆栈[1]。

gcc可以使用-S开关向您显示汇编代码,查看内容以了解正在发生的事情,以及--param min-pretend-dynamic-size是否会对您产生任何影响平台和功能。

在你的情况下,另一个解决方案是将while()循环的主体移动到一个新函数中,因为这将创建/销毁包含classA对象的堆栈帧。

[1] gcc docs:

<强>最小假装-动态尺寸

  

强制任何大小(以字节为单位)等于或大于的自动对象   比动态分配的指定值,就像它们的大小一样   不知道编译时间。这使他们的存储成为可能   在包含它们的块的末尾释放,减少总堆栈   如果多个使用重堆栈的函数被内联到a中,则使用   单一功能。它对合适的对象没有任何影响   用于分配寄存器(即,足够小和   没有他们的地址),也没有分配的对象   函数的最外面的块。默认值为零会导致其对象   在编译时已知大小以在函数处分配存储   条目。