Jump to content

    
Метценгерштейн

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

Recommended Posts

Есть проект на ++, из отладки доступно только логи, типа 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 , что проект падает.

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

Share this post


Link to post
Share on other sites
16 minutes ago, Метценгерштейн said:

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

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

Share this post


Link to post
Share on other sites

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

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

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

так?

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

Share this post


Link to post
Share on other sites
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 );

 

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Linux платформа

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

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

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

дает вывод

tst_vers2 = 0x4

Что странно

 

Share this post


Link to post
Share on other sites
(1) const char * tst_vers2 = device_firmware->version()->c_str();

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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:

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

 

Share this post


Link to post
Share on other sites
8 minutes ago, Метценгерштейн said:

код

дает вывод:

tst_vers2 = 0x4
tst_vers3 = 0x3ffe8d1c

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

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

 

Share this post


Link to post
Share on other sites
Just now, Метценгерштейн said:

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

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

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

Share this post


Link to post
Share on other sites

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

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

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

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

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

Share this post


Link to post
Share on other sites
4 minutes ago, k155la3 said:

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

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

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.