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

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

 

23 minutes ago, haker_fox said:

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

Это?

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

Я не очень понял что имелось ввиду

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


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

26 minutes ago, haker_fox said:

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

Изучил матчасть. Спасибо за инф. Похоже на копировщик.

может 

static char ms1[1000];

char *p_ms1 = &ms1[0]; 

p_ms1 = device_firmware->version()->c_str();

 

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

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

Я не очень понял что имелось ввиду

что к моменту, когда вы выполняете присваивание указателю, для дальнейшего использования результата, эта область памяти уже используется для других целей и может быть занята чем угодно. Или не используется, тогда это создает ложное впечатление, что все работает "как надо".

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


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

Тяжелый синтаксис тут.

путь следования до
 

device_firmware->version()->c_str()

Вот файл с вызовом

 const flatbuffers::String *version() const {
    return GetPointer<const flatbuffers::String *>(VT_VERSION);
  }

идем в другой файл

struct String : public Vector<char> {
  const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
  std::string str() const { return std::string(c_str(), size()); }

  // clang-format off
  #ifdef FLATBUFFERS_HAS_STRING_VIEW
  flatbuffers::string_view string_view() const {
    return flatbuffers::string_view(c_str(), size());
  }
  #endif // FLATBUFFERS_HAS_STRING_VIEW
  // clang-format on

  bool operator<(const String &o) const {
    return StringLessThan(this->data(), this->size(), o.data(), o.size());
  }
};

 

8 minutes ago, k155la3 said:

может 

static char ms1[1000];

char *p_ms1 = &ms1[0]; 

p_ms1 = device_firmware->version()->c_str();

мне это проделать? Не понял

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


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

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

Тяжелый синтаксис тут.

. . . .

мне это проделать? Не понял

тяжелый - не то слово :)))

Для проверки, попробуйте. Если это метод копирования, оно предполагает не просто указатель, а указатель на Вашу, выделенную Вами область памяти. Зачем объекту расходовать и держать свою память для затребованной Вами инфорамции (строки).

А поскольку там в коде вижу и шаблоны и итд итп, что мне глубоко чуждо. :girl_cray2: не исключено, что где-то "перегружена" операция присваивания и слева не просто переменная, а аргумент для метода-копировщика. Это, как-бы, "для упрощения чтения кода" :)))

ps

(?) где-то . . . в std::   ?

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


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

		static char ms1[1000];
        const char *p_ms1 = &ms1[0];
        p_ms1 = device_firmware->version()->c_str();
        ESP_LOGI(TAG, "az p_ms1 = %p", p_ms1);

const добавил- ругалось

вывод:

az p_ms1 = 0x4
 

Т.е. ничего не поменялось. По мне- и не должно было. Т.к. оно таким уже приходит к нам сюда.

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


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

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

 


device_firmware->version()->c_str()

Вот файл с вызовом

 const flatbuffers::String *version() const {
    return GetPointer<const flatbuffers::String *>(VT_VERSION);
  }

 

проверяли, что уходит по return ?

и что есть VT_VERSION. 

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

		static char ms1[1000];
        const char *p_ms1 = &ms1[0];
        p_ms1 = device_firmware->version()->c_str();
        ESP_LOGI(TAG, "az p_ms1 = %p", p_ms1);

const добавил- ругалось

вывод:

az p_ms1 = 0x4
Т.е. ничего не поменялось. По мне- и не должно было. Т.к. оно таким уже приходит к нам сюда.

Да, первоначальный указатель на static массив затерся. Перегузки "=" нет.

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


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

21 minutes ago, k155la3 said:

и что есть VT_VERSION. 

немного полнее - это структура

struct DeviceFirmware FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_VERSION = 4,
    VT_TYPE = 6,
    VT_RELEASE_TIMESTAMP = 8,
    VT_FIRMWARE = 10,
    VT_MD5_CHECKSUM = 12,
    VT_CHUNK_NUMBER = 14,
    VT_LAST_CHUNK = 16,
    VT_LAST_TRANSFER = 18
  };
  const flatbuffers::String *version() const {
    return GetPointer<const flatbuffers::String *>(VT_VERSION);
  }

 

23 minutes ago, k155la3 said:

проверяли, что уходит по return ?

значит, можно как-то вызвать

device_firmware->version()

так?

так упал проект. Т.е. вернуло что-то опять не то.

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


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

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

немного полнее - это структура



    VT_VERSION = 4,
   

 

не исключено что эта четверка соответствует "глючному" указателю 0x4

return GetPointer<const flatbuffers::String *>(VT_VERSION);

Смотрите реализацию GetPointer().  Там что-то "не сложилось" и вместо  значения-"указателя" из таблицы по индексу 4 вернуло само 4.  ps. не индекс, а смещения. (FlatBuffersVTableOffset)

Шаблон, не знаю. даже то что не знаю, забыл.

код GetPointer() есть ?

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


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

1 hour ago, k155la3 said:

код GetPointer() есть ?

 template<typename P> P GetPointer(voffset_t field) {
    auto field_offset = GetOptionalFieldOffset(field);
    auto p = data_ + field_offset;
    return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p))
                        : nullptr;
  }

может и да, 4- это что вернуло как значение из таблицы. Но я ведь могу поменять значение. Проверю.

смущает что код

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

без проблем отрабатывает и возвращает и корректный адрес указателя и значение- саму строку.

вот полностью кусок файла- чтобы была картина более полная

struct DeviceFirmware FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_VERSION = 4,
    VT_TYPE = 6,
    VT_RELEASE_TIMESTAMP = 8,
    VT_FIRMWARE = 10,
    VT_MD5_CHECKSUM = 12,
    VT_CHUNK_NUMBER = 14,
    VT_LAST_CHUNK = 16,
    VT_LAST_TRANSFER = 18
  };
  const flatbuffers::String *version() const {
    return GetPointer<const flatbuffers::String *>(VT_VERSION);
  }
  flatbuffers::String *mutable_version() {
    return GetPointer<flatbuffers::String *>(VT_VERSION);
  }
  DataSchema::FirmwareType type() const {
    return static_cast<DataSchema::FirmwareType>(GetField<int8_t>(VT_TYPE, 0));
  }
  bool mutate_type(DataSchema::FirmwareType _type) {
    return SetField<int8_t>(VT_TYPE, static_cast<int8_t>(_type), 0);
  }
  uint32_t release_timestamp() const {
    return GetField<uint32_t>(VT_RELEASE_TIMESTAMP, 0);
  }
  bool mutate_release_timestamp(uint32_t _release_timestamp) {
    return SetField<uint32_t>(VT_RELEASE_TIMESTAMP, _release_timestamp, 0);
  }
  const flatbuffers::Vector<int8_t> *firmware() const {
    return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_FIRMWARE);
  }
  flatbuffers::Vector<int8_t> *mutable_firmware() {
    return GetPointer<flatbuffers::Vector<int8_t> *>(VT_FIRMWARE);
  }
  const flatbuffers::String *md5_checksum() const {
    return GetPointer<const flatbuffers::String *>(VT_MD5_CHECKSUM);
  }

Я про md5_checksum- там тот же GetPointer этот

2 hours ago, k155la3 said:

не исключено что эта четверка соответствует "глючному" указателю 0x4

return GetPointer<const flatbuffers::String *>(VT_VERSION);

все равно возврат

tst_vers2 = 0x4

хотя 5 было указано. Так что просто совпадение

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


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

 template<typename P> P GetPointer(voffset_t field)      // P == flatbuffers::String *
 {
    auto field_offset = GetOptionalFieldOffset(field);
    auto p = data_ + field_offset;

    return 
            field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p)) : nullptr;
// если field_offset некорректно, вернуть nullptr (ошибка). 
// p + ReadScalar<uoffset_t>(p) - похоже к адресу "базы" p прибавить смещение, записанное по адресу p (суде по enum, оно 2-байтное)
// иначе, взять адрес вычисленный как: data_ ("база0" файла), + смещение от начала файла с индексом[field=4]==field_offset и преобразовать 
// резултат в тип flatbuffers::String *. return;
  }

Функция вернет за счет шаблонности + reinterpret_cast указатель на любой тип, который будет указан в переменной шаблона. Соотв-но надо на 100 проц. быть уверенным, что по индексу "4" вычисленный адрес соответствует именно строке, а не числу float например.

А есть гарантия, что в "файле" из которого считываются эти данные, все "на своем месте" ?

Там упоминается MD5. Возможно имеет смысл проверить целостность "файла".

Я бы промониторил значения data_ и field_offset  - для функции, которая отрабатывает успешно, и для ошибочной.

(да, метод полутыка)

Наличие "файла" в виде бинарника сильно упростило бы задачу.

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


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

On 4/1/2020 at 7:50 PM, k155la3 said:

Перегузки "=" нет.

Перегрузки "operator=" у "const char *" ?

Удивительно просто.

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


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

17 minutes ago, esaulenka said:

Перегрузки "operator=" у "const char *" ?

Удивительно просто.

Мне подсказали, что c_str() это из std::string::c_str.  Там перегрузка есть.

Да, компилятор в этом случае выдал бы ошибку.

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


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

16 minutes ago, k155la3 said:

Мне подсказали, что c_str() это из std::string::c_str.  Там перегрузка есть.

В данном случае c_str() это из гугловского flatbuffer::String::c_str.

 

И любая перегрузка operator= - это для синтаксиса наподобие

ла_ла_ла.c_str() = "ла-ла-ла", которого нет ни в стандартной библиотеке, ни (насколько мне известно) в велосипедах "по образу и подобию".

 

 

Ну а автору я б посоветовал читать книжки (уже пора) и изучить слово GDB.

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


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

On 4/3/2020 at 12:26 PM, esaulenka said:

Ну а автору я б посоветовал читать книжки (уже пора) и изучить слово GDB.

Да прочитано много книжек. Не первый же год я в программировании)

Тут жопа полная, а не проект

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


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

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

Да прочитано много книжек. Не первый же год я в программировании)

Тут жопа полная, а не проект

Проблемы не в проектах, а в головах

Untitled.jpg.ca21ef580c58424e30e1aed1e7939699.jpg

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


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

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

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

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

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

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

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

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

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

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