[英]Crash: When accessing vector from class
我正在編寫ESP32 UI,並遇到了以下問題:
我有一個類Menu,並在其標題中定義了一個向量_menuItemStack。
我從外部創建一個對象MenuItem並將其傳遞給函數addMenuItem(MenuItem menuItem)。 它將其添加到堆棧中。 當我在Menu.cpp中聲明矢量時,它會運行。 但這對於每個對象來說不是唯一的,我認為它變成靜態的了嗎?
所以我在頭文件中將向量聲明為私有,同時它將進行編譯。 它立即崩潰。
我怎么了 C ++讓我頭疼。
Menu.h
/*
Menu.h - Menu Class
*/
#ifndef Menu_h
#define Menu_h
#include "Arduino.h"
#include "StackArray.h"
#include "MenuItem.h"
#include "SPI.h"
#include "U8g2lib.h"
class Menu
{
public:
Menu();
void update();
void draw();
void addMenuItem(MenuItem menuItem);
private:
int arrayPos;
std::vector<MenuItem> _menuItemStack;
};
#endif
Menu.cpp
#include "Menu.h"
extern U8G2_SSD1327_MIDAS_128X128_2_4W_HW_SPI u8g2;
Menu::Menu() {
arrayPos = 0;
}
void Menu::draw() {
u8g2.setFont(u8g2_font_6x10_tf);
int posY = 0;
for (MenuItem &m : _menuItemStack){
u8g2.drawStr(0,posY+15,m.getText().c_str());
posY+=15;
}
}
void Menu::update() {
}
void Menu::addMenuItem(MenuItem menuItem){
arrayPos++;
_menuItemStack.push_back(menuItem);
//debug
Serial.println(arrayPos);
Serial.println(menuItem.getText());
}
注意:std :: stdlib在更高的位置。
編輯:
MenuItem.cpp
#include "MenuItem.h"
extern U8G2_SSD1327_MIDAS_128X128_2_4W_HW_SPI u8g2;
MenuItem::MenuItem() {
_text = new String;
}
MenuItem::MenuItem(const MenuItem &obj){
_text = new String;
*_text = *obj._text;
}
void MenuItem::draw(){
}
void MenuItem::update(){
}
void MenuItem::setText(String txt){
*_text = txt;
}
String MenuItem::getText(){
return *_text;
}
void MenuItem::attachHandler(CallbackFunction f){
callback = f;
}
void MenuItem::run(){
if (callback != NULL) callback();
}
MenuItem.h
#ifndef MenuItem_h
#define MenuItem_h
#include "Arduino.h"
#include "StackArray.h"
#include "SPI.h"
#include "U8g2lib.h"
class MenuItem
{
private:
typedef void (*CallbackFunction)();
CallbackFunction callback = NULL;
String *_text;
public:
MenuItem();
MenuItem(const MenuItem &obj);
void draw();
void update();
void run();
void setText(String txt);
void attachHandler(CallbackFunction f);
String getText();
};
#endif
當您調用std::vector::push_back
您將創建對象的副本並將其存儲到向量中。 因此,首先檢查類的副本構造函數,以及是否可能由該原因引起錯誤。
然后,您需要知道std::vector
所需的內存存儲在哪里。
在嵌入式目標上,您可能沒有使用傳統的標准庫,並且操縱內存可能很棘手。
當將向量聲明為全局變量時,很有可能與將其聲明為類的私有成員時所需的內存不在同一區域。 這將取決於您的平台,編譯器,鏈接器腳本以及您使用的lib C ++。 std::vector
使用一個分配器,在Linux上您可以不用看它做什么,而在嵌入式目標上時,您需要知道您正在使用哪個分配器以及內存在哪里。
您可以嘗試打印std::vector::data()
的地址以進行檢查。 然后,您可能必須提供自己的分配器,或保留足夠大的內存部分來容納向量,並在此內存地址處初始化向量中包含的數據。
傳遞給addMenuItem
函數的menuItem
是一個副本,該副本的壽命直到該函數結束為止。
嘗試傳遞菜單項作為參考,以便將使用壽命比addMenuItem
函數長的對象填充菜單項列表。 更改簽名看起來像這樣:
void Menu::addMenuItem(MenuItem& menuItem)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.