Я пишу программу для создания, отправки, получения и интерпретации ARP-пакетов. У меня есть структура, представляющая ARP заголовок так:C++ массивы переменной длины в структуре
struct ArpHeader
{
unsigned short hardwareType;
unsigned short protocolType;
unsigned char hardwareAddressLength;
unsigned char protocolAddressLength;
unsigned short operationCode;
unsigned char senderHardwareAddress[6];
unsigned char senderProtocolAddress[4];
unsigned char targetHardwareAddress[6];
unsigned char targetProtocolAddress[4];
};
это работает только для аппаратных адресов с длиной 6 и адресами протокола с длиной 4. Длина адреса приведена в заголовке, а также, так быть правильны структура должна выглядеть примерно так:
struct ArpHeader
{
unsigned short hardwareType;
unsigned short protocolType;
unsigned char hardwareAddressLength;
unsigned char protocolAddressLength;
unsigned short operationCode;
unsigned char senderHardwareAddress[hardwareAddressLength];
unsigned char senderProtocolAddress[protocolAddressLength];
unsigned char targetHardwareAddress[hardwareAddressLength];
unsigned char targetProtocolAddress[protocolAddressLength];
};
это, очевидно, не будет работать, так как длина адреса не известна во время компиляции. Структуры шаблонов не являются опцией, так как я хотел бы заполнить значения для структуры, а затем просто отбросить ее (ArpHeader *) до (char *), чтобы получить массив байтов, который можно отправить в сети или сделать полученный массив байтов от (char *) до (ArpHeader *), чтобы интерпретировать его.
Одним из решений было бы создать класс со всеми полями заголовка в качестве переменных-члена, функцию для создания массива байтов, представляющего заголовок ARP, который может быть отправлен в сети, и конструктор, который принимает только массив байтов (полученный в сети) и интерпретировать его, читая все поля заголовка и записывая их в переменные-члены. Это нехорошее решение, так как для этого потребуется LOT больше кода.
В отличие от аналогичной структуры для UDP-заголовка, например, просто, поскольку все поля заголовка имеют известный постоянный размер. Я использую
#pragma pack(push, 1)
#pragma pack(pop)
вокруг объявления структуры, так что я могу на самом деле сделать простой бросок C-стиле, чтобы получить массив байтов для отправки в сети.
Есть ли какое-нибудь решение, которое я мог бы использовать здесь, которое было бы близко к структуре или, по крайней мере, не требовало бы намного большего количества кода, чем структура? Я знаю, что последнее поле в структуре (если это массив) не нуждается в определенном размере времени компиляции, могу ли я использовать что-то подобное для моей проблемы? Просто оставляя размеры этих 4 массивов пустыми, будет компилироваться, но я понятия не имею, как это будет функционировать. Просто логически это не сработает, поскольку компилятор понятия не имел, где начинается второй массив, если размер первого массива неизвестен.
Если максимальный размер адреса равен 6, вы не можете сделать массивы размера [6], а затем интерпретировать их соответственно? Это самое простое решение, если вы хотите избежать большого количества кода.Другим вариантом было бы использовать один большой массив фиксированной длины для всех адресов и написать функцию, которая будет готовить массив байтов на основе длин адресов –
Матрицы с нулевой длиной или гибкие члены массива недействительны C++. – pmr
Почему бы не использовать std :: string или std :: vector как член структуры? И если вы используете структуру, почему вы не предоставляете им функциональность? Разделение кода на данные и программу в точности противоположно объектно-ориентированному программированию. Ваш вопрос сам по себе звучит как неудача дизайна! – Klaus