2

我正在尝试定义一个结构的实例,并且在设置这个变量时遇到了特别的麻烦。它是一个 char 数组。

这是我的头文件中的结构...

struct widget_t {
    char *name;
    uint8_t numberOfNicknames;
    char *nicknames[];
};

这是我试图设置widget_t结构的实例......

widget_t SomeWidget;

void setUpFunction () {
    SomeWidget.name = (char *)"Lawn Mower";
    SomeWidget.numberOfNicknames = 2;
    SomeWidget.nicknames = {
        "Choppie McGrasschopper",
        "Really Noisy"
    };
}

因此,当我尝试将昵称放入SomeWidget.nicknames. 我不确定我是否需要做一些时髦的事情,就像我正在做name的指针一样......?

棘手的一点是数量nicknames是可变的。因此,每个实例都希望设置不同数量的它们。

4

4 回答 4

1

The problem you have, is that c++ does not support variable arrays. Instead you will have to allocate memory dynamically using new or in your case new[].

First you need to change your data type to char**, almost equaliant to the one before. Then you can allocate as many strings you want like this nicknames = new char*[number_of_nicknames].

Important is that with this method you will have to delte your nicknames manually like this: delete[] nicknames;. The best way to accomplish this is using RAII (delete your nicknames in your deconstructor)

When you have dynamic strings then you would use the following structure

struct widget_t {
    // optional constructor to allocate nicknames

    ~widget_t()
    {
        for (int i = 0; i < numberOfNicknames; ++i)
        {
            char* nickname = nicknames[i];

            if (nickname)
                delete[] nickname;
        }

        delete[] nicknames;
    }

    char *name;
    uint8_t numberOfNicknames;
    char **nicknames = NULL;
};

and with constant string the next

struct widget_t {
    // optional constructor to allocate nicknames
    // allocate nicknames like
    // -> nicknames = new const char*[numberOfNicknames];

    ~widget_t()
    {
         if (nicknames) delete[] nicknames;
    }

    char *name;
    uint8_t numberOfNicknames;
    const char **nicknames = NULL;
};
于 2019-01-16T08:15:01.760 回答
0
于 2019-01-16T08:10:59.063 回答
0

One option would be:

struct widget_t {
    char const *name;
    uint8_t numberOfNicknames;
    char const * const *nicknames;
};

static char const *mower_nicknames[] = { "Choppie", "Bob" };
widget_t SomeWidget = { "Lawn Mower", 2, mower_nicknames };

static char const *bus_nicknames[] = { "Wheels", "Go", "Round" };
widget_t OtherWidget = { "Bus", 3, bus_nicknames };

// no setup function needed
于 2019-01-16T08:59:56.807 回答
0

There are different problems here.

First your last member in of an incomplete type because it is an array of undeclared dimension. This is not allowed in C++ but most compilers allows it as an extension with same semantics as C. This is rather tricky to use anyway, because it can only be used with allocated structs, where you allocate memory for the struct itself and the incomplete array.

Next, you are trying to assign to a array. You cannot. Arrays are not first class objects in C++ (nor in C). You can initialize an array as a whole, but can only assign to an array element.

And last, you are assigning a C litteral string to a char *. This is bad, because the standard declares that litteral strings are const so using later the pointer to change a char would be Undefined Behaviour. It will work if you do not, but the pointers should at least be declared as const.

Here is how you could use all that:

widget_t* setUpFunction () {
    // allocates a widget_t with 2 slots in nicknames
    widget_t *someWidget = (widget_t *) malloc(sizeof(widget_t) + 2 * sizeof(char *));
    someWidget.name = (char *)"Lawn Mower";   // VERY DANGEROUS: pointer should be const
    someWidget.numberOfNicknames = 2;
    someWidget.nicknames[0] = (char *) "Choppie McGrasschopper"; // SAME DANGER
    someWidget.nicknames[1] = (char *) "Really Noisy"            // Still same danger
    return widget_t;
}

But all this is rather C-ish and should be avoided in C++. In addition, it still requires allocated memory, which may not be what you want for Arduino

于 2019-01-16T09:46:16.150 回答