Перейти к содержанию
    

странность с выводом строки char *

Есть проект на ++, из отладки доступно только логи, типа printf.

Получаю в ф-ю объект (device_firmware), где есть две строки по указателю, их и присваиваю новым указателям на char tst_vers2  и tst_vers3

const char * tst_vers2 = device_firmware->version()->c_str();
const char * tst_vers3 = device_firmware->md5_checksum()->c_str();

И тут начинаются странности, если сделать вывод строк, то строка tst_vers3 выводится, или сделать 

ESP_LOGI(TAG, "tst_vers3 = %d", strlen(tst_vers3));

то тоже выводится кол-во знаков (32), а вот если сделать вывод tst_vers2 , то проект падает.

Если с tst_vers2  попробовать вывести strlen- тоже падает.

Мне банально не посмотреть что такого в этом tst_vers2 , что проект падает.

Что можно придумать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 minutes ago, Метценгерштейн said:

Мне банально не посмотреть что такого в этом tst_vers2 , что проект падает.

Выведете адрес, который находится в указателе tst_vers2. Проверьте, что адрес правильный (можно проверить по map-файлу). Возможно, строка не содержит терминирующий символ. Обычно это '\0'. Похэтому стандартная процедура вывода, не встречая этого терминатора, не останавливается во-время, идёт по адресам, забредает в несуществующие/запрещённый для чтения и т.п. Отсюда и падение программы. Можете вывести по-символьно в цикле содержимое по адресу. Скажем, первые 10 символов. Проверьте, что там ваша строка.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я уже делал memcpy в созданный массив. Падает

Может я не то делаю. Попрошу строчку кода привести.

ESP_LOGI(TAG, "tst_vers2 = %d", (int)tst_vers2);

так?

лог для вывода адреса

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, Метценгерштейн said:

лог для вывода адреса

Не знаю, как у вас устроена ESP_LOGI. Но в формате стандартного printf так

type_t * ptr = &address_of_some_variable; // type_t любой тип
printf( "My ptr address is 0x%x\r\n", ptr );
// Можно так
printf( "My ptr address is %p\r\n", ptr );

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, Метценгерштейн said:

я уже делал memcpy в созданный массив. Падает

Может я не то делаю. Попрошу строчку кода привести.


ESP_LOGI(TAG, "tst_vers2 = %d", (int)tst_vers2);

так?

смотря какая платформа. Если PC, то указатель Вы так не распечатаете. Да и не надо это.

Напишите просто код (цикл) который смотрит первые 100 байт по указателю, ищет этот 0. + простой printf("Ok")

 

1 minute ago, haker_fox said:

Не знаю, как у вас устроена ESP_LOGI. Но в формате стандартного printf так


type_t * ptr = &address_of_some_variable; // type_t любой тип
printf( "My ptr address is 0x%x\r\n", ptr );

 

Надо смотреть док., если задача распечатать именно указатель, то там может быть %p.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Linux платформа

Считаем, что синтаксис как printf.

ESP_LOGI(TAG, "az tst_vers2 = %p", tst_vers2);

ESP_LOGI(TAG, "tst_vers2 = %p", tst_vers2);

дает вывод

tst_vers2 = 0x4

Что странно

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(1) const char * tst_vers2 = device_firmware->version()->c_str();

(2) const char * tst_vers3 = device_firmware->md5_checksum()->c_str();

объявление класса device_firmware можете выложить ?

Меня что-то два "->" и два метода в одной строке смущают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

код

ESP_LOGI(TAG, "tst_vers2 = %p", tst_vers2);
ESP_LOGI(TAG, "tst_vers3 = %p", tst_vers3);

дает вывод:

tst_vers2 = 0x4
tst_vers3 = 0x3ffe8d1c
 

очень странно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вангую у ТСа внутри version() и md5_checksum() есть объекты класса CString в локальной памяти (на стеке). И он возвращает указатели на них. От которых потом берёт c_str().  :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, k155la3 said:

объявление класса device_firmware можете выложить ?

попробую. Только там матрешка целая.

Вот объявил:

        // Output the data obtained
        const DataSchema::DeviceFirmware* device_firmware_flatbuffers =
            DataSchema::GetDeviceFirmware(builder.GetBufferPointer());

        ota.handle_firmware_data(device_firmware_flatbuffers);

вызвал handle_firmware_data.

Вот получил это в handle_firmware_data:

ota_error_t OTA::handle_firmware_data(const DataSchema::DeviceFirmware *device_firmware) {
  ...

там уже делаю эти вызовы. Точнее, еще в одну ф-ю передаю тот же объект device_firmware. Но, думаю, не критично это.

5 minutes ago, jcxz said:

Вангую у ТСа внутри version() и md5_checksum() есть объекты класса CString в локальной памяти (на стеке). И он возвращает указатели на них. От которых потом берёт c_str().  :biggrin:

что можно посмотреть, чтобы это узнать? Код не мой, приехал мне в таком виде))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, Метценгерштейн said:

код

дает вывод:

tst_vers2 = 0x4
tst_vers3 = 0x3ffe8d1c

0x04 - фонарь.  Проверяйте согласованность работы ф-ий преобразования. Для md5 (число как-никак) подойдет sscanf( . . .  %.8X, &dst);

а если версию FW так "обработать", вроде "1.1.0.33" то ничего хорошего из этого не выйдет (и ltoa() тоже ). Отсюда может быть и возврат "фонарного" указателя. 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, k155la3 said:

0x04 - фонарь.

это как? В смысле, труба дело? Это и так понятно. Откуда вылезло?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, Метценгерштейн said:

это как? В смысле, труба дело? Это и так понятно. Откуда вылезло?

просмотрите все реализации ф-ии метода c_str() (он может быть один, а может быть и несколько, в зависимости от типа аргумента, который оно обрабатывает на входе). На "входе" может быть число бинарное, флоат, поле с версией FW, итд. На выходе оно  c_str() должно выдать символьную строку. Если не выдает - значит что-то не отработало (вернее отработало, но с ошибкой), и возможно "фонарный" указатель - индикация ошибки. Хотя в этих случаях обычно возвращают NULL. 

В частности, проверьте, корректно ли преобразуется в сторку значение FW (не знаю в каком оно виде, самые разные варианты могут быть)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

фонарный указатель- это код ошибки? 4 мои?

Может c_str() некорректно работает, но соседняя ф-я его корректно обрабатывает же.

(1) const char * tst_vers2 = device_firmware->version()->c_str();

(2) const char * tst_vers3 = device_firmware->md5_checksum()->c_str();

Может не в нем дело?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, k155la3 said:

просмотрите все реализации ф-ии метода c_str()

Это из стандартной библиотеки) Вот.

1 minute ago, Метценгерштейн said:

Может не в нем дело?

А вы проверили это?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...