在函数中获取原始类型的指针

时间:2018-08-25 11:56:56

标签: c++ arduino esp32

我有一个联合(ValueDefinition),其中包含不同数据类型的指针,并具有创建它的功能。使用String可以正常工作:

ValueDefinition CreateValDefString(String value){
        ValueDefinition valDef = {.ValueString = new String(value)};
        return valDef;
    }

但是当我用例如uint8_t可以编译,但是在运行时出现此错误:

[E][WString.cpp:185] changeBuffer(): realloc failed! Buffer unchanged

这是uint8_t的代码:

ValueDefinition CreateValDefUint8(uint8_t value){
    ValueDefinition valDef = {.ValueUInt8 = new uint8_t(value)};
    return valDef;
}

我在做什么错?我在没有“ new”和malloc的情况下尝试了该方法,但是仍然遇到相同的错误。

编辑:根据要求,ValueDefinition的定义:

 union ValueDefinition{
     bool* ValueBool;
     int8_t* ValueInt8;
     int16_t* ValueInt16;
     int32_t* ValueInt32;
     uint8_t* ValueUInt8;
     uint16_t* ValueUInt16;
     uint32_t* ValueUInt32;
     float* ValueFloat;     
     ulong* ValueULong;
     String* ValueString;
 };

1 个答案:

答案 0 :(得分:2)

在您的代码中,C ++似乎向函数抛出错误以创建WString而不是uint8_t,因此stacktrace在完全独立的标头中。在存储库的源代码中搜索arduino,表明WString.cpp here中存在错误,这是编译器正在检测的。

github用户建议使用其他字符串库,由于该错误尚未修复,因此您必须进行更改,可能要更改为C ++定义的标准string库,而则不能 > arduino。如用户在github上所述,众所周知,arduino字符串不可靠。

换句话说,此错误与您的代码无关,但是我想问的一个问题是“为什么在C ++中使用联合?”如果要定义通用类型,只需在类型声明中使用尖括号,例如:

 class ValueDefinition<T> {
 private:
     T typeDat;
 public:
     Valuedefinition<T>(T t);
     /* etc. */
 }

创建了联合,以便C可以通过让多个类型在联合中共享数据来使用通用类型。另一个常见用途是利用数据类型使用相同的内存来查找更复杂类型的基础二进制文件,例如使用位于uint8_t下的单个long long值来查找其位的值或使用int以获取float的二进制值,例如:

union foo {
   uint8_t bits[4]; /* Represent the bits of 'data' */

   long long int data;
}

union foo myLong = {.data = 12378591249169278l};
printf("%d\n", myLong.bits[0]); // Returns the value of the high bit of myLong

但是请注意,这是未定义的行为,因为unions are usually padded,因此无论如何都不要尝试。无论您在做什么,如果使用C ++,都有比使用联合更好的解决方案,因为这是针对没有通用类型in order to save memory的语言的功能。

编辑: 像这样,使用C样式的内存管理初始化ValueDefinition:

union ValueDefinition *value = malloc(sizeof(union ValueDefinition));
value->ValueUInt8 = malloc(sizeof(uint8_t));
/* more code */

或与C ++的new

union ValueDefinition *value = new ValueDefinition();
value->ValueUInt8 = new uint8_t(/* Some number */);
/* more code */