Способ создания структуры переменного размера
-
06-07-2019 - |
Вопрос
Мне нужно создать пакет с заголовком, трейлером и полем полезной нагрузки переменной длины.До сих пор я использовал вектор для полезной нагрузки, поэтому моя структура настроена следующим образом:
struct a_struct{
hdr a_hdr;
vector<unsigned int> a_vector;
tr a_tr;
};
Когда я пытаюсь получить доступ к элементам вектора, я получаю ошибку seg, и sizeof всей структуры дает мне 32 (после того, как я добавил около 100 элементов в вектор.
Хороший ли это подход?Что может быть лучше?
Я нашел этот пост Структура переменного размера C ++ Он использовал массив символов, а я, тем не менее, использую вектор.
Решение
Решение в другом ответе SO зависит от c и основано на особенностях c-массивов - и даже в c sizeof () не поможет вам найти " true " размер переменной размера структуры. По сути, это мошенничество, и это вид мошенничества, который не является необходимым в C ++.
То, что вы делаете, прекрасно. Чтобы избежать ошибок сегмента, обращайтесь к вектору так же, как к любому другому вектору в C ++:
a_struct a;
for(int i = 0; i < 100; ++i) a.a_vector.push_back(i);
cout << a.a_vector[22] << endl; // Prints 22
Другие советы
Несмотря на то, что тип vector встроен в структуру, единственным элементом, который есть в векторе, скорее всего, является указатель.Добавление элементов в вектор приведет к увеличению размера не самого векторного типа, а памяти, на которую он указывает.Вот почему вы никогда не увидите увеличения размера структуры в памяти и, следовательно, получите ошибку seg.
Обычно, когда люди хотят создать структуру переменного размера, они делают это, добавляя массив в качестве последнего члена структуры и устанавливая его длину равной 1.Затем они выделят дополнительную память для структуры, которая на самом деле требуется sizeof(), чтобы "расширить" структуру.Это почти всегда сопровождается дополнительным элементом в структуре, детализирующим размер расширенного массива.
Причина использования 1 подробно задокументирована в блоге Рэймонда
я видел эту реализацию в boost .. выглядит действительно аккуратно ... иметь переменную длина полезной нагрузки ....
class msg_hdr_t { public: std::size_t len; // Message length unsigned int priority;// Message priority //!Returns the data buffer associated with this this message void * data(){ return this+1; } // };
это может быть совершенно не связано с вопросом, но я хотел бы поделиться информацией