使用指向类的指针时 RAM 使用错误

RAM usage wrong when using pointers to class

本文关键字:错误 指针 RAM      更新时间:2023-10-16

我不明白编译器如何估计RAM使用率。我做了以下MCVE。 编译后(Arduino nano ATMEGA328P,新的引导加载程序(,Arduino编译器显示的RAM使用率是错误的。我比较了以两种方式创建DataContainer结构体的实例,一个是使用指针数组并使用new调用构造函数(运行时,堆?这是正确的名称吗(和只创建一个结构数组(编译时?(。

#include <Arduino.h>
struct DataContainer {
int values[100] = {0}; // init to zeros
void FillRandom() {
for (int k = 0; k < 100; k++)
values[k] = random(0, 200);
}
};
class ExampleClass 
{
public:
DataContainer *data[20]; // Heap, runtime?
// DataContainer data[20]; // or compile time
ExampleClass() {
for (int k = 0; k < 20; k++)
data[k] = new DataContainer(); // not necessary when using: DataContainer data[20]
}
};
// declare class
ExampleClass EC;
void setup() {
// call constructor
EC = ExampleClass();
EC.data[1]->FillRandom(); // for run time
// EC.data[1].FillRandom();  // for compile time
}

如果我比较编译器显示的 RAM 使用情况,我会看到以下内容。

案例 1,使用DataContainer *data[20];

RAM:   [          ]   3.1% (used 63 bytes from 2048 bytes)
Flash: [=         ]   5.8% (used 1782 bytes from 30720 bytes)

案例 2,使用DataContainer data[20];

RAM:   [==========]  195.9% (used 4013 bytes from 2048 bytes)
Flash: [          ]   3.9% (used 1194 bytes from 30720 bytes)

(我知道这不适合 Arduino,仅举个例子(。

有没有办法仍然获得RAM使用情况的估计值?

不要在 16 位 MCU 上使用动态分配。 尤其是不是在纳米上。 只是没有足够的内存。

估计所需的 RAM 空间很简单。

  1. 计算结构的大小。

    struct DataContainer { 整数值[100] = {0};初始化为零/* ... */};

100 x sizeof(int( = 100 x 2 = 200。

  1. >计算数组的大小。

    数据容器数据[20];

20 x 200 = 4000 字节。

关于你的代码的一些说明。

// declare class
ExampleClass EC;   //  Good!  On small MCUs, global variables are the thing!
//  Note that the constructor HAS BEEN called.
void setup() {
// call constructor
EC = ExampleClass();    // ???  Why are you creating a new object???
// creating a 4000 bytes object on the stack 
// is a sure way to crash your app.  I give it
// no more than a couple of microseconds before 
// crashing on a nano.
// This line of code is not needed, EC is already 
// initialized.
// Always leave room on the stack, it's needed for 
// calling functions and also for interrupts.
/* ... */
}

说明:此行EC = ExampleClass();堆栈上创建一个临时对象,然后将其复制到全局变量 EC 中。

编译器指示仅 4000 字节已用内存的原因是堆栈空间不包括在计数中。 您的代码需要 4000 字节的全局内存 RAM + 4000 字节用于堆栈上的临时变量,然后还需要更多才能运行。