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() + меньше переменных было правильным способом сэкономить память

, 👍0

Обсуждение

переменные, объявленные внутри функций, создаются в стеке, общий размер этих переменных составляет 4 КБ - 3900 приближается к этому - вы захотите использовать mallocfree), чтобы вместо этого использовать кучную память, @Jaromanda X

другой вариант: если вы знаете, какой может быть абсолютная максимальная полезная нагрузка, создайте глобальный буфер для использования, @Jaromanda X


1 ответ


Лучший ответ:

0

Локальная переменная функции создается в стеке, а в случае 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