Jump to content

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

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

Recommended Posts

 

23 minutes ago, haker_fox said:

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

Это?

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

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

Share this post


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

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

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

Share this post


Link to post
Share on other sites

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

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

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();

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

Share this post


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

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

. . . .

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

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

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

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

ps

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

Share this post


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

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

Share this post


Link to post
Share on other sites
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 массив затерся. Перегузки "=" нет.

Share this post


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

так?

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

Share this post


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

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



    VT_VERSION = 4,
   

 

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

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

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

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

код GetPointer() есть ?

Share this post


Link to post
Share on other sites
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 было указано. Так что просто совпадение

Share this post


Link to post
Share on other sites
 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  - для функции, которая отрабатывает успешно, и для ошибочной.

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

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

Share this post


Link to post
Share on other sites
17 minutes ago, esaulenka said:

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

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

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

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

Share this post


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

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

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

 

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

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

 

 

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

Share this post


Link to post
Share on other sites
On 4/3/2020 at 12:26 PM, esaulenka said:

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

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

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

Share this post


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

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

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

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

Untitled.jpg.ca21ef580c58424e30e1aed1e7939699.jpg

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.