Получение указателя типа примитива в функции

У меня есть объединение (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;
};

0

Решение

В вашем коде похоже, что C ++ выдает ошибку функции, чтобы создать WString вместо uint8_tследовательно, трассировка стека в совершенно отдельном заголовке. Поиск исходного кода в хранилище для arduino показывает, что в WString.cpp есть ошибка Вот, это то, что обнаруживает ваш компилятор.

Пользователи github предлагают использовать другую библиотеку строк, и, поскольку ошибка не устранена, вам придется изменить ее, возможно, на стандартную. string библиотека определяется C ++ и не 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

Однако обратите внимание, что это неопределенное поведение так как союзы обычно дополняются, так что не пытайтесь это делать ни в коем случае. Что бы вы ни делали, если вы используете C ++, есть лучшее решение, чем использование союзов, так как это была функция, предназначенная для языка, который не имел универсальной типизации чтобы сохранить память.

Редактировать:
Инициализируйте ValueDefinition следующим образом, используя управление памятью в стиле C:

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 */
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]