Как определить фактическое использование буфера malloc'ed - PullRequest
0 голосов
/ 18 ноября 2011

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

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

Ответы [ 5 ]

2 голосов
/ 18 ноября 2011

Как уже говорили другие, нет хорошего способа сделать это, если ваш API этого не предоставляет.

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

Эвристика должна была бы заполнить ваш буфер каким-нибудь «ядовитым» шаблоном, прежде чем распаковывать его. Затем, после распаковки, отсканируйте буфер для первого появления шаблона отравления.

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

Даже в лучшем случае несовершенное решение.

0 голосов
/ 28 марта 2012

вы должны проверить, как бесплатно работает ваш компилятор / ОС и сделай то же самое. free не берет размер ошибочных данных, но он каким-то образом знает, сколько нужно освободить;) обычно размер хранится перед выделенным буфером, хотя точно не знаю, сколько байтов будет раньше, в зависимости от os / arch / compiler

0 голосов
/ 14 декабря 2011

Сложный способ решить эту проблему - распаковать дважды в буфер большого размера.

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

Или это так?Возможно, случайно один из последних байтов распакованной последовательности соответствует случайному байту в этой точной позиции.Таким образом, окончательный распакованный размер может быть больше, чем обнаруженный.Если ваш шаблон действительно случайный, он не должен превышать нескольких байтов.

Вам необходимо снова заполнить буфер случайным шаблоном, но другим.Убедитесь, что в каждой позиции новый случайный шаблон имеет значение, отличное от старого случайного шаблона .Для более быстрой скорости вы не обязаны заполнять полный буфер: вы можете ограничить новый шаблон несколькими байтами до и еще несколькими байтами после первого обнаруженного конца.32 байта должно быть достаточно, поскольку маловероятно, чтобы такое количество байтов случайно соответствовало первому сгенерированному случайному шаблону.

Распакуйте во второй раз.Определите снова, где образец отличается.Возьмите большее из двух значений между первым и вторым концом обнаружения.Это ваш распакованный размер.

0 голосов
/ 18 ноября 2011

Если шаг распаковки не дает вам распакованный размер в качестве возвращаемого значения или параметра "out" каким-либо образом, вы не можете.

Невозможно определить, сколько данных было записанов буфере (вне проверок типа отладчика / valgrind).

0 голосов
/ 18 ноября 2011

Обычно эта информация предоставляется во время сжатия (посмотрите, например, на 7-zips LZMA SDK).

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

...