簡體   English   中英

調整struct / char數組的大小(以減少內存使用)

[英]Resizing struct / char array (to reduce memory usage)

這是我在Arduino / C ++ / ESP32上的第一個項目。 我寫了一個相當大的程序,幾乎所有東西都可以工作-到最后,我意識到設備會周期性地耗盡呼吸(內存)並重新啟動。 重新啟動是因為我配置了監視程序來執行此操作。

我認為有一個地方可以減少內存使用量,但是我對c ++的經驗“還不存在”,我可以自己編寫。 請問任何指針(無雙關語)? 從昨天開始,我一直在研究這個問題,而擺脫一個錯誤只會導致彈出另一個新錯誤。 而且,我不想提出一些有問題的東西或以后可能會損壞的東西。 對於這里有經驗的人來說,這應該是一個快速的答案。

讓我解釋一下我更喜歡重構/優化的代碼。

我需要存儲一堆記錄,以后需要閱讀/操作。 我全局聲明了一個struct( 因為它們是相關字段 )。 現在的問題是,我可能需要存儲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上的Q&A時,我嘗試了一些隨機的東西,至少下面這段代碼似乎起作用了(就存儲較小/較大的值而言)

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上)都是一個壞主意。

您將此問題標記為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()覆蓋

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM