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

时间:2019-04-14 17:22:06

标签: c++ arduino esp32

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

我认为有一个领域可以减少内存使用,但是我对c ++的经验“还不存在”,这样我就可以自己编写了。请问任何指针(无双关语)?从昨天开始,我一直在研究这个问题,而摆脱一个错误只会导致弹出另一个新错误。而且,我不想提出一些有问题的东西或以后可能会损坏的东西。对于这里有经验的人来说,这应该是一个快速的答案。

让我解释一下我希望重构/优化的代码。

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

总结

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

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

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

stUSRREC userRecords[NumOfrecs];

我使自己熟悉了诸如strcpy,memset,malloc等一整套功能,但是现在我已经没有时间了,需要继续学习另一天。

我可以尝试以略有不同的方式执行此操作,其中我不使用该结构,而是使用单独的char数组(用于每个字段,如username)。但是,当我从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等小型设备加载一堆东西时,这些约束会变得更加明显。我已经使用“ Strings”(大写的S)完成了所有工作,但是定期重新启动(cpu饿死?)需要我摆脱Strings。甚至在其他情况下,我也听说使用Strings(在ESP,Arduino和gang上)是个坏主意。

1 个答案:

答案 0 :(得分:3)

您将此问题标记为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);

您可能不再需要NumOfrecsuserRecrods.size()

已涵盖
相关问题