реализовать указатель на структуру переменного размера - PullRequest
1 голос
/ 16 июля 2011

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

например:

struct info_t {
   UINT32 signature;
   UINT32 elements[NUM_ELEMENTS];
   UINT32 options;
};

NUM_ELEMENTS генерируется динамически, и известно только во время выполнения, переменная elements должна иметь размер точно NUM_ELEMENTS, иначе переменная options будет иметь неправильное смещение.

Я счастлив, если смогу инициализировать указатель структуры, когда это необходимо, но C ++ не позволит мне избежать неизвестной переменной NUM_ELEMENTS во время компиляции.Есть идеи?Спасибо.

Ответы [ 5 ]

2 голосов
/ 16 июля 2011

Обычно вы помещаете значения переменной длины в конец, а затем вынимаете его как массив и выделяете его, например, в vector. Этот вид кода обычно не используется в C ++.

2 голосов
/ 16 июля 2011

Массивы переменной длины (VLA) не поддерживаются стандартом C ++.
C ++ предоставляет std :: vector для этого.

1 голос
/ 16 июля 2011

Попробуйте написать класс-обертку, который получает данные и предоставляет функции-члены для доступа к данным в хорошем чистом виде, а затем посмотрите, насколько быстро это происходит. Это может быть уже достаточно быстро.

0 голосов
/ 16 июля 2011

Изображение (кода) - это более тысячи слов:

// --> do not instantiate a static variable of these:

struct info_t_headerstruct {
   UINT32 signature;
   UINT32 options;
   UINT32 num_elements;
   // no elements !!!
};

// --> do not instantiate a static variable of these, either:

// header plus variable elements
struct info_t_struct {
   info_t_headerstruct header;
   UINT32 elements[65535]; 
};

// --> you will use this type instead:

typedef
  info_t_struct* info_t_ptr;

info_t_ptr generate(size_t variableqty)
{
  size_t HowManyBytes = (sizeof(info_t_headerstruct) + (sizeof UINT32  * variableqty));
  info_t_ptr Result = malloc(HowManyBytes);
}

// ...

void doSomething(info_t_ptr dataptr)
{
  dataptr = generate(5);
  // ...
}

Это один из тех случаев, когда вы можете избавиться от идеи «все - это класс / объект»,Я обычно использую "struct" в C ++ так же, как и в "plain C", как данные, а не как класс / объект.

Как упоминалось в предыдущем ответе.Вы должны переместить элементы или переменные данные в нижний колонтитул типа данных.

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

Вы будете работать с указателем структуры, а не самой структурой.

Некоторые [университетский проект / компания] нестандартные версии «pascal» или «plain C» поддерживают этот тип функции в синтаксисе.

0 голосов
/ 16 июля 2011

Я предполагаю, что info_t - это формат данных, которые вы пытаетесь проанализировать, поэтому вы не можете его изменить.

Есть ли какая-то конкретная причина, по которой использование класса-оболочки не поддается управлению?Кажется, это именно та проблема, где ООП полезен.Если вам не нужен класс, интерфейс которого совместим с info_t, вы можете использовать следующую компоновку:

struct info_t {
   UINT32 &signature;
   UINT32 * const elements;
   UINT32 &options;
};

Затем необходимо создать конструктор, который устанавливает поля, указывающие на правильные местоположения в вашемвходные данные.

Если ваши входные данные задаются как указатель на массив UINT32, конструктор может выглядеть примерно так:

info_t(UINT32 *data, size_t number_of_elements) :
    signature (*data),
    elements (data+1),
    options (*(data+number_of_elements+1)) {}

Если вы хотите, чтобы data был освобожденкогда экземпляр info_t выходит из области видимости, вы можете сделать это в конструкторе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...