【问题标题】:Arduino - only first object loses its data property value when contained in a collection/array in another objectArduino - 当包含在另一个对象的集合/数组中时,只有第一个对象会丢失其数据属性值
【发布时间】:2014-02-17 03:43:51
【问题描述】:

考虑 Arduino 的以下代码。它编译并运行,但不提供预期的输出。

class Item {
    private :
        int val;

    public :
        int get(){
            return val;
        };
        void set(int v) {
            val = v;
        };
};

class Sub{
    private :
        Item * items;
        int writeIndex;
    public :
        Sub(){
            writeIndex = 0;
        };
        void addItem(Item * obj) {
            items[writeIndex] = *obj;
            writeIndex++;
        };
        int get(int in) {
            return items[in].get();
        };
};

class Main{
    private:
        Sub * sub;

    public:
        void setSub(Sub * s) {
            sub = s;
        };

        int get(int in) {
            return sub->get(in);
        };
};

Main m;
Sub s;
Item i1;
Item i2;
Item i3;
Item i4;

void setup(){
    Serial.begin(115200);
    while(!Serial) {}

    i1.set(4);
    i2.set(5);
    i3.set(6);
    i4.set(7);

    s.addItem(&i1);
    s.addItem(&i2);
    s.addItem(&i3);
    s.addItem(&i4);

    m.setSub(&s);
}

void loop(){
    int v = 0;
    for(int i = 0; i < 4; i++) {
        v = m.get(i);
        Serial.println(v);
    }
    delay(10000);
}

输出如下: 0 5 6 7

但它应该打印: 4 5 6 7

为什么第一个 Item 对象似乎失去了它的赋值?

【问题讨论】:

    标签: c++ arrays oop object arduino


    【解决方案1】:

    嗯,实际上,你很幸运它可以打印任何东西!

    您的问题是您实际上并没有为您的数组分配任何内存,如果我删除所有Sub 样板,您的代码实际上如下:

    Item i1, i2, i3, i4;
    i1.set(4);
    i2.set(5);
    i3.set(6);
    i4.set(7);
    
    // Sub()
    Item * items;
    int writeIndex;
    writeIndex = 0;
    // s.addItem(&i1)
    items[writeIndex] = &i1;
    writeIndex++;
    // s.addItem(&i2)
    items[writeIndex] = &i2;
    writeIndex++;
    // s.addItem(&i3)
    items[writeIndex] = &i3;
    writeIndex++;
    // s.addItem(&i4)
    items[writeIndex] = &i4;
    writeIndex++;
    

    事情是,Item* items 是一个未定义的指针,因此包含一个未知值。因此,当您执行items[writeIndex] 时,您正在访问位于items 指针中包含的随机值位置的内存。

    如果它“以某种方式”有效,那是你很幸运能够拥有看起来“几乎”有效的“随机”值,但完全错误

    为了解决这种情况,您需要为items 数组分配内存。在堆栈中创建时给它一个大小:

    #define SUB_LENGTH 5 // store up to 5 values
    Item items[SUB_LENGTH]
    

    或者通过从堆中分配内存:

    Item* items;
    Sub() {
        items = (Item*) malloc(SUB_LENGTH);
    }
    

    如果您选择第一个选项,则必须在 addItem() 中添加最大长度检查:

    bool addItem(Item* obj) {
        if (writeIndex >= SUB_LENGTH)
            return false;
        items[writeIndex] = *obj;
        writeIndex++;
        return true;
    }
    

    如果您选择第二个选项,您可以进行最大长度检查,或使用realloc() 重新分配内存以增加内存大小。我没有给你一个实现的例子,因为如果你需要改变数组的大小,你可能更喜欢实现一个链表(或者使用一个已经存在的linked list)。

    【讨论】:

    • 谢谢。我在这里使用了在 arduino 论坛上找到的矢量实现:forum.arduino.cc/index.php/topic,45626.0.html,它运行良好,没有太多过载。
    • 我从代码中删除了它,但是有一个 SubItem 构造函数添加了类似 Item items[] = {};编译器允许我这样做,但如果我错了,请纠正我,但我将无法使用 items[0] = something, items[1] = something 稍后添加项目?是这样吗?
    • Vector() : d_size(0), d_capacity(0), d_data(0) {}; : 之后的部分是什么意思(即 d_size(0),...) 是默认值吗?
    • 1/ 好吧,确实,items[] = {} 声明了一个大小为 0 的数组,所以你会遇到同样的麻烦。 2/ 为什么你从基于 vector 的工作版本更改为非工作数组版本? 3/ 是的,在构造函数中分配成员是一种 C++ 语法。
    • 2/ :我做了相反的事情!,从指针混乱的非工作版本更改为向量:现在它可以工作了!。但是这段代码是对更复杂代码的过度简化......并且由于某种原因它不适用于向量......但“为什么”是我必须自己找到的。
    猜你喜欢
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 2015-06-07
    • 2016-04-20
    • 2015-01-10
    相关资源
    最近更新 更多