调整结构/字符数组的大小(以减少内存使用)



这是我在Arduino/C++/ESP32上的第一个项目。我写了一个相当大的程序,几乎一切都可以正常工作 - 除了最后我意识到设备会定期耗尽呼吸(内存)并重新启动。重新启动是因为我配置了一个看门狗来执行此操作。

有一个领域我认为有机会减少内存使用,但我在 c++ 方面的经验"还没有"让我能够自己编写它。请问任何指针(没有双关语)?从昨天开始,我一直在做这件事,摆脱一个错误只会导致另一个新错误弹出。此外,我不想想出一些笨拙或以后可能会破坏的东西。对于这里有经验的人来说,这应该是一个快速的答案。

让我解释一下我更喜欢重构/优化的代码。

我需要存储一堆稍后需要读取/操作的记录。我全局声明了一个结构(因为它们是相关字段)。现在的问题是我可能需要存储 1 条记录、2 条记录或 5 条记录,这些记录只有在我从 EEPROM 读取数据后才会知道。这必须是所有功能都可以访问的,因此它必须是一个全球宣言。

总结一下

问题1- 一旦从EEPROM读取数据,如何在程序的后面设置"NumOfrecs"。

问题 2- 字符数组用户名的大小(sizeOfUsername) 也可以根据从 eeprom 读取的用户名的长度而变化。有时长度可能为 5 个字符,有时可能是 25 个字符。我可以将其设置为最大 25 并解决此问题,但如果许多用户名只有 4-5 个字符长,我不会浪费内存吗?简而言之 - 就在将 eeprom 中的数据复制到"用户名"字符数组之前,是否可以将其大小设置为保存该数据所需的最佳大小(即数据大小 + 1 字节用于空终止)。

struct stUSRREC {
char username[sizeOfUsername];
bool online;
}; 
stUSRREC userRecords[NumOfrecs];

我熟悉了一大堆函数,如strcpy,memset,malloc等,但现在我已经没有时间了,需要将学习部分保留一天。

我可以尝试以稍微不同的方式执行此操作,其中我不使用结构,而是使用单独的字符数组(对于每个字段,如用户名)。但话又说回来,当我从 eeprom 读取数据时,我将不得不调整数组的大小。

我可以解释我尝试过的所有事情,但这会使这个问题变得不必要地冗长,并可能导致失去一些清晰度。非常感谢任何帮助。

在回应SO的问答时,我正在尝试一些随机的东西,至少下面的这一小段代码似乎有效(在存储较小/较大的值方面)

struct stUSRREC {
char username[];        
bool online;                   
}; 
stUSRREC userRecords[5];

然后以这种方式操纵它

strcpy(userRecords[0].username, "MYUSERNAME");
strcpy(userRecords[0].username, "test");
strcpy(userRecords[0].username, "MYVERYBIGUSERNAME");

我已经能够编写/重写不同的长度(上图),并且可以正确读取所有这些长度。调整"userRecords"的大小可能是一个不同的游戏,但可以稍等片刻

我忘了提到的一件事是,我只需要调整数组的大小/大小(持有用户名)一次。在setup()本身中,我可以将所需的数据读取/加载到这些数组中。我不确定这是否开辟了任何其他可能性。我需要在运行过程中操作的其余结构/数组只是布尔值和整数值。这根本不是问题,因为这样做不需要调整大小。

附带说明一下,我很确定我不是唯一一个面临这种情况的人。任何提示/线索/指针都可以对许多其他人有所帮助。当您真正开始加载一堆东西时,像 ESP32 这样的小设备的限制会变得更加明显。我让所有内容都与"字符串"(大写的 S)一起使用,但定期重启(CPU 饥饿?)要求我摆脱字符串。即使不然,我听说使用字符串(在ESP,Arduino和gang上)是一个坏主意。

你把这个问题标记为C++,所以我会问:

您可以在嵌入式代码中使用vectorstring吗?

#include <string>
#include <vector>
struct stUSRREC {
std::string username;
bool online;
stUSRREC(const char* name, bool isOnline) :
username(name), 
online(isOnline)
{
}
};
std::vector<stUSRREC> userRecords;

使用string作为用户名类型意味着您只需分配保存名称所需的字符数,而不是分配假定的最大大小sizeOfUsername。 使用vector可以动态增长记录集。

然后添加新记录:

stUSRREC record("bob", true);
userRecords.push_back(record);

您可能不再需要NumOfrecs了。 这被userRecrods.size()所涵盖

最新更新