我有一个相当大的 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
的全局变量和变量在程序的整个生命周期中都存在 - 自动变量(在函数或方法内声明的变量)在其范围的生命周期内存在,包括从该范围调用的任何其他子程序的生命周期
- 动态分配是从
new
1 或alloc
函数族(总是比您出于簿记原因要求的大小)从您分配它们时一直持续到您调用delete
或free
(分别)。
1 如果您覆盖 new
,这可能仍然适用,也可能不适用,但如果您这样做,您需要了解自己对自己做了什么。
关于c++ - 在 Arduinos 上,函数内的变量是否始终保留在 RAM 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13663669/