簡體   English   中英

崩潰:從類訪問向量時

[英]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.

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