Хорошее представление байтового массива и его размера

Как бы вы представили байтовый массив и его размер? Я хотел бы хранить (в основной памяти или в файле) необработанные байтовые массивы (символы без знака), в которых первые 2/4 байта будут представлять его размер. Но операции с таким массивом выглядят не очень хорошо:

void func(unsigned char *bytearray)
{
int size;
memcpy(&size, bytearray, sizeof(int));
//rest of operation when we know bytearray size
}

Как я могу избежать этого? Я думаю о простой структуре:

struct bytearray
{
int size;
unsigned char *data;
};

bytearray *b = reinterpret_cast<bytearray*>(new unsigned char[10]);
b->data = reinterpret_cast<unsigned char*>(&(b->size) + 1);

И у меня есть доступ к размеру и части данных bytearray. Но все равно выглядит некрасиво. Не могли бы вы порекомендовать другой подход?

0

Решение

Вы эффективно заново изобретаете «Строка Паскаля». тем не мение

 b->data = reinterpret_cast<unsigned char*>(&(b->size) + 1);

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

Вы должны иметь возможность использовать массив с неопределенным размером для последнего элемента структуры:

struct bytearray
{
int size;
unsigned char data[];
};

bytearray *b = reinterpret_cast<bytearray*>(::operator new(sizeof (bytearray) + 10));
b->size = 10;

//...

::operator delete(b);

В отличие от std::vectorэто на самом деле сохраняет размер и данные вместе, так что вы можете, например, записать их в файл за одну операцию. И местность памяти лучше.

Тем не менее, тот факт, что std::vector уже протестирован и реализовано много полезных алгоритмов, что делает его очень привлекательным.

2

Другие решения

Если у вас нет веской причины поступить иначе, просто сделайте идиоматическую вещь и используйте std :: vector<символ без знака>,

5

я хотел бы использовать std::vector<unsigned char> управлять памятью и написать функцию преобразования для создания некоторых iovec как структура для вас в то время, когда вам нужна такая вещь.

iovec make_iovec (std::vector<unsigned char> &v) {
iovec iv = { &v[0], v.size() };
return iv;
}

С помощью iovecЕсли вам нужно записать длину и данные в одном системном вызове, вы можете использовать writev призыв к выполнению этого.

ssize_t write_vector(int fd, std::vector<unsigned char> &v) {
uint32_t len = htonl(v.size());
iovec iv[2] = { { &len, sizeof(uint32_t) }, make_iovec(v) };
return writev(fd, iv, 2);
}
2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector