Способ создания структуры переменного размера - PullRequest
0 голосов
/ 19 июня 2009

Мне нужно создать пакет с заголовком, трейлером и полем полезной нагрузки переменной длины. До сих пор я использовал вектор для полезной нагрузки, поэтому моя структура настроена так:

struct a_struct{
 hdr a_hdr;
 vector<unsigned int> a_vector;
 tr a_tr;
};

Когда я пытаюсь получить доступ к членам вектора, я получаю ошибку сегмента, и размер целых структур дает мне 32 (после того, как я добавил около 100 элементов к вектору.

Это хороший подход? Что лучше?

Я нашел это сообщение Структура переменного размера C ++ Он использовал массив символов, а я использую вектор.

Ответы [ 3 ]

5 голосов
/ 19 июня 2009

Несмотря на то, что векторный тип встроен в структуру, единственный член в векторе, вероятно, является указателем. Добавление членов к вектору не увеличит размер самого векторного типа, но память, на которую он указывает. Вот почему вы никогда не увидите увеличения структуры в памяти и, следовательно, получите ошибку сегмента.

Обычно, когда люди хотят создать структуру переменного размера, они делают это, добавляя массив в качестве последнего члена структуры и устанавливая его длину равным 1. Затем они выделяют дополнительную память для структуры, которая фактически требуется для sizeof. () для того, чтобы «расширить» структуру. Это почти всегда сопровождается дополнительным членом в структуре, детализирующим размер расширенного массива.

Причина использования 1 тщательно задокументирована в блоге Рэймонда

2 голосов
/ 19 июня 2009

Решение в другом ответе SO зависит от c и основано на особенностях массивов c - и даже в c sizeof () не поможет вам найти «истинный» размер структуры переменного размера. По сути, это мошенничество, и это своего рода обман, который не нужен в 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
1 голос
/ 19 июня 2009

я видел эту реализацию в 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; }  //
};

это может быть совершенно не связано с вопросом, но я хотел бы поделиться информацией

...