c++ - 在 Arduinos 上,函数内的变量是否始终保留在 RAM 中?

标签 c++ memory memory-management arduino

我有一个相当大的 Arduino 草图,它正在插入处理器上可用内存的限制。我正在释放内存并尽可能减少对全局变量的使用。我正在使用 MemoryFree.h(可以找到详细信息 here)来检查可用内存。我有一个工作草图(太长无法在此处发布)但是当我添加另一个带有几个变量的函数(在我认为可用内存范围内)时,我的系统由于没有内存而崩溃或停止。

我添加了以下功能:

boolean moved(){

int yreadings[4];
int zreadings[4];


free(&yreadings);
free(&zreadings);
}

然后我将以下代码添加到我的主循环中:

 Serial.print("Mem is ");
 Serial.println(freeMemory());
 moved();

如果循环中的 moved() 和下面的整个函数被注释掉,我得到的输出是

Mem is 499

在每次迭代中,表明每次迭代都没有内存丢失。

然而,如果我取消注释该函数并调用它,我会得到以下输出:

Mem is 499
Mem is -16094

在崩溃前的第一行和第二行...

即使内存是持久的,每次迭代使用的内存不应该比整个 499 字节少得多吗?不过,我怎么会失去任何内存呢?

更新: 更奇怪的是:如果我删除 moved() 函数并全局声明整数数组,我仍然会得到 499 的内存读数。这是怎么回事?它不应该减少 24 个整数消耗的内存量吗?

最佳答案

如果您只需要为函数执行的一部分存在自动存储,您可以将它们放在一个作用域 block 中:

void foo(void) {

   // some code where neither reading variable is occupying memory

   {
      int yreadings[4];
      int zreadings[4];

      // here these variable are taking up memory

   }

   // other code where neither reading variable is occupying memory
}

但是当然你只能在那个 block 中使用它们。


为了扩展我的评论,有三类具有不同持续时间的内存使用

  • 在函数或方法或类上下文中声明为 static 的全局变量和变量在程序的整个生命周期中都存在
  • 自动变量(在函数或方法内声明的变量)在其范围的生命周期内存在,包括从该范围调用的任何其他子程序的生命周期
  • 动态分配是从 new1alloc 函数族(总是比您出于簿记原因要求的大小)从您分配它们时一直持续到您调用 deletefree(分别)。

1 如果您覆盖 new,这可能仍然适用,也可能不适用,但如果您这样做,您需要了解自己对自己做了什么。

关于c++ - 在 Arduinos 上,函数内的变量是否始终保留在 RAM 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13663669/

相关文章:

memory - 如何以编程方式判断 Linux 处于 PAE 模式还是非 PAE 模式?

c - 在声明函数之外访问二维数组中的结构

memory-management - 在 Swift 程序中有必要使用 autoreleasepool 吗?

c++ - 错误 C2039 : 'next' : is not a member of 'chain<T>' with [T=Person]

c# - 将折线转换为具有宽度的多边形形状

c++ - 枚举元组类型的最佳方法?

python - 从内存位置的哈希查找中删除列表中的项目?

c++ - Qt Creator 调试器不显示 char* 和 wchar_t* 变量的文本内容

C# .NET Core 2.1 Span<T> 和 Memory<T> 性能注意事项

memory - 为什么 dotmemory 在尝试附加到实时进程时无法收集内存流量和堆栈跟踪信息