首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >调整struct / char数组大小(以减少内存使用量)

调整struct / char数组大小(以减少内存使用量)
EN

Stack Overflow用户
提问于 2019-04-15 01:22:06
回答 1查看 390关注 0票数 -1

这是我在Arduino/C++/ESP32上的第一个项目。我写了一个相当大的程序,让几乎所有的东西都工作了--除了最后我意识到设备会周期性地耗尽呼吸(内存)并重新启动。重新启动是因为我配置了一个watchdog来执行此操作。

我认为有一个领域有机会减少内存使用,但我在c++上的经验“还没有”让我能够自己写这篇文章。有什么建议吗(不是双关语)?我从昨天开始就一直在做这件事,摆脱一个错误只会导致另一个新的错误出现。此外,我不想提出一些老生常谈的东西,或者以后可能会崩溃的东西。对于这里有经验的人来说,这应该是一个快速的答案。

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

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

用于汇总的

问题1 -从eeprom读取数据后,如何在程序中稍后设置"NumOfrecs“。

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

代码语言:javascript
复制
struct stUSRREC {
  char username[sizeOfUsername];
  bool online;
}; 

stUSRREC userRecords[NumOfrecs];

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

我可以尝试用一种稍微不同的方式来实现这一点,我不使用struct,而是使用单独的char数组(对于每个字段,如username )。但是,当我从eeprom读取数据时,我将不得不重新调整数组的大小。

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

在回答Q&A时,我尝试了一些随机的东西,至少下面这小段代码似乎可以工作(在存储更小/更大的值方面)

代码语言:javascript
复制
struct stUSRREC {
  char username[];        
  bool online;                   
}; 

stUSRREC userRecords[5];

然后这样操作它

代码语言:javascript
复制
strcpy(userRecords[0].username, "MYUSERNAME");
strcpy(userRecords[0].username, "test");
strcpy(userRecords[0].username, "MYVERYBIGUSERNAME");

我已经能够写/重写不同的长度(如上),并且可以正确地读回所有的长度。调整"userRecords“的大小可能是另一回事,但可以稍等片刻。

我忘记提到的一件事是,我只需要调整数组的大小/大小(保存用户名)一次。在setup()本身中,我可以将所需的数据读取/加载到这些数组中。我不确定这是否会带来任何其他可能性。我需要在运行期间操作的结构/数组的其余部分只是布尔值和int值。这根本不是问题,因为这样做不需要调整大小。

顺便说一句,我非常确定我不是唯一一个面临这种情况的人。任何提示/线索/指针都可能对其他许多人有所帮助。当你真正开始加载一堆东西时,像ESP32这样的小设备上的约束就会变得更加明显。我用“字符串”(大写的S)就行了,但是周期性的重启(cpu饥饿?)需要我处理掉这些字符串。即便如此,我也听说使用字符串(在ESP、Arduino和gang上)不是一个好主意。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-15 01:57:30

您将此问题标记为C++,因此我将询问:

你能在你的嵌入式代码中使用vectorstring吗?

代码语言:javascript
复制
#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作为用户名类型意味着您只分配保存名称所需的任意数量的字符,而不是分配假定的最大大小sizeOfUsernamevector的使用允许您动态地增加记录集。

然后添加新记录:

代码语言:javascript
复制
stUSRREC record("bob", true);
userRecords.push_back(record);

而且您可能不再需要NumOfrecs。这是由userRecrods.size()介绍的

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55678021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档