崩溃:从类

时间:2019-03-14 15:01:43

标签: c++ arduino esp32

我正在编写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

2 个答案:

答案 0 :(得分:0)

调用std::vector::push_back时,将创建对象的副本并将其存储到向量中。因此,请首先检查您的类的副本构造函数,以及是否可能由该错误引起。

然后,您需要知道std::vector所需的存储器存储在哪里。

在嵌入式目标上,您可能未使用传统的标准库,并且操纵内存可能很棘手。

当将向量声明为全局变量时,与将其声明为类的私有成员时相比,所需的内存很有可能不在同一区域中。这将取决于您的平台,编译器,链接器脚本以及您使用的lib C ++。 std::vector使用分配器,在Linux上您可以不用看它做什么,而在嵌入式目标上时,您需要知道您正在使用哪个分配器以及内存在哪里。

您可以尝试打印std::vector::data()的地址进行检查。然后,您可能必须提供自己的分配器,或保留足够大的内存部分来容纳向量,并在此内存地址处初始化向量中包含的数据。

答案 1 :(得分:0)

传递给menuItem函数的addMenuItem是一个具有寿命的副本,直到该函数结束为止。

请尝试传递菜单项作为参考,以便将使用寿命比addMenuItem函数长的对象填充菜单项列表。这样将签名更改为:

void Menu::addMenuItem(MenuItem& menuItem)