为什么指向 class 的指针比 "classic" 变量占用更少的内存 SRAM

Why a pointer to a class take less memory SRAM than a "classic" variable

我有一个 Arduino Micro,上面焊接了 3 个飞行时间激光雷达微型传感器。在我的代码中,我创建了 3 个这样的全局变量:

Adafruit_VL53L0X lox0 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox1 = Adafruit_VL53L0X();
Adafruit_VL53L0X lox2 = Adafruit_VL53L0X();

它占用了大约 80% 的内存 现在我正在像这样创建我的对象

Adafruit_VL53L0X *lox_array[3] = {new Adafruit_VL53L0X(), new Adafruit_VL53L0X(), new Adafruit_VL53L0X()};

它占了我整个程序的 30%

我试着查看 arduino 文档,但我没有找到任何可以帮助我的东西。 我可以理解创建一个“经典”对象可以填充内存。但是创建指针时内存区域位于何处?

两种方式都使用相同数量的内存。(实际上,第二种方式使用了一点点更多,因为指针也需要存储。)

只是对于第一种方式,内存已经从程序的开始和部分数据大小静态分配,所以你的编译器可以告诉你它,而对于第二种方式,内存是在运行时动态分配(在堆上),因此您的编译器事先不知道它。

我敢说第二种方法更危险,因为考虑以下场景:假设您的其他代码和数据在编译时已经使用了 90% 的内存。如果您使用第一种方法,您将无法上传程序,因为它现在会使用大约 150% 的资源,所以您已经知道它不会工作。但是,如果您使用第二种方法,您的程序将编译和上传得很好,但在运行时尝试分配额外内存时会崩溃。

(顺便说一句,编译器消息有点不完整。它应该说“为局部变量和动态分配的对象[=留出 1750 个字节32=]" 或者类似的东西)。

你可以使用这个函数自己检查它,它允许你在运行时估计空闲内存量(通过比较堆的顶部和堆栈的底部[物理上,而不是逻辑上],后者是实现通过查看此时已在堆栈上分配的局部变量的地址):

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

另请参阅:https://playground.arduino.cc/Code/AvailableMemory/