ESP8266 аварийно завершает работу при попытке скопировать строку в большой символ.
Я пытаюсь проанализировать с помощью tinyxml2 скромный XML (3,4 КБ), чтобы получить некоторые данные.
Мой ESP8266 аварийно завершает работу каждый раз, когда я пытаюсь использовать метод toCharArray
.
вот мой код
// здесь я получаю http-запрос
String payload = https.getString();
// проверка полезных данных, в консоли все нормально, но при выводе àèéùìò я получаю какие-то мусорные символы
Serial.println(payload);
// Длина (с одним дополнительным символом для нулевого терминатора)
int str_len = payload.length() + 1;
// Подготавливаем массив символов
char xml[str_len];
// Копируем его
payload.toCharArray(xml, str_len);
// там я разбираю xml с помощью tinyxml2, но MCU выходит из строя, прежде чем добраться сюда
Длина строки около 3900, и я не уверен, что она поместится в такой массив на этом устройстве. Если это так, то какая стратегия будет лучшей?
Как вы понимаете, я только начинаю изучать язык Си :)
РЕДАКТИРОВАТЬ: https.getString().c_str()
+ меньше переменных было правильным способом сэкономить память
@Daniele, 👍0
Обсуждение1 ответ
Лучший ответ:
Локальная переменная функции создается в стеке, а в случае ESP8266 общий размер ограничен 4096 байтами, поэтому 3900 для одной переменной очень мало.
Я бы порекомендовал вам использовать malloc/free
int str_len = payload.length() + 1;
// Подготавливаем массив символов
char *xml = (char *) malloc(str_len);
// Копируем его
payload.toCharArray(xml, str_len);
// там я разбираю xml с помощью tinyxml2, но MCU выходит из строя, прежде чем добраться сюда
//
// когда закончим, освободим память, выделенную malloc
free(xml);
или, если вы знаете абсолютный максимальный размер строки, например 5000, создайте char xml[5001];
в глобальной области видимости
попробовал объявить символ размером 6000 в глобальном масштабе, и он перезагружается <<<стек<<< ets, 8 января 2013 г., первая причина: 2, режим загрузки: (3,6) загрузка 0x4010f000, len 1384, комната 16 хвост 8 контрольная сумма 0x2d csum 0x2d v951aeffa, размер строки ~5700, @Daniele
получил ошибку компиляции с помощью malloc -> src/main.cpp:74:35: ошибка: недопустимое преобразование из 'void*' в 'char*' [-fpermissive], @Daniele
да, извини, спешил - подожди - вот, исправил, @Jaromanda X
попробовал объявить символ размером 6000 в глобальном масштабе, и он перезагружается
- правда? это кажется странным, @Jaromanda X
все еще не повезло (событие с malloc, которое, кажется, работает нормально), но я думаю, что проблема может быть в другом месте. Для документации я опубликую суть основного файла -> https://gist.github.com/leRenart/1b72db23371839fd5a7799ece63ad8ed., @Daniele
так что с malloc происходит сбой по той же «причине»?, @Jaromanda X
он выходит из строя каждый раз, когда я выполнял myString.toCharArray(), поэтому я, наконец, решил избавиться от некоторых переменных и закончил передачу результата GET непосредственно в синтаксический анализатор xml doc.Parse( https.getString() .c_str() );
Я тестировал его в течение многих часов без каких-либо проблем. Я думаю, что использовал слишком много памяти, но опять же, я не уверен (если вы хотите взглянуть на мой код, я опубликовал его суть). Это меня расстраивает, потому что без видимой причины (поскольку входные данные те же) сегодня утром продолжает падать, и я не могу понять, почему. Для меня всему этому можно научиться (неправильно) делая..., @Daniele
- Как разделить входящую строку?
- Как вывести несколько переменных в строке?
- форматирование строк в Arduino для вывода
- Очень простая операция Arduino Uno Serial.readString()
- DateTime в строку
- Как преобразовать строку в массив байтов
- Как отправить строку на мастер с помощью i2c
- Создание форматированной строки (включая числа с плавающей запятой) в Arduino-совместимом C++
переменные, объявленные внутри функций, создаются в стеке, общий размер этих переменных составляет 4 КБ - 3900 приближается к этому - вы захотите использовать
malloc
(иfree
), чтобы вместо этого использоватькучную
память, @Jaromanda Xдругой вариант: если вы знаете, какой может быть абсолютная максимальная полезная нагрузка, создайте глобальный буфер для использования, @Jaromanda X