LINUX.ORG.RU

Хитрый memcpy

 , ,


0

4

Есть ли в стандартной библиотеке такой memcpy:

    char data[size];
    char* currentPointer = data;
    memcpy(&currentPointer,someData,someDataSize);
    //currentPointer += someDataSize;  <-- вот этот кусок кода должен выполнится во время memcpy


Верный ответ man mempcpy
Хитрый memcpy (комментарий)

★★★★★

//currentPointer += someDataSize; <-- вот этот кусок кода должен выполнится во время memcpy

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

Bad_ptr ★★★★ ()
Ответ на: комментарий от Bad_ptr

Делаю сериализацию/десериализацию. Сначала все сохраняю в char*, потом оттуда считываю. Вот эти вот += уже писать поднадоело. Думал, что-нибудь стандартное уже есть.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

Вот эти вот += уже писать поднадоело.

ну можно ещё макрос написать. Хотя странно это, что уж так часто тебе писать приходиться этот +=. Может там цикл какой привинтить или ещё что.
ну тады, когда будешь писать, добавь ещё параметр max_size, чтоб проверяло на переполнение.

char data[max_size];
memcpy(&currentPointer,someData,someDataSize,max_size);

Bad_ptr ★★★★ ()
Ответ на: комментарий от KennyMinigun

Спасибо за ссылку, полезная информация.
Один вопрос, сереалайз ведь вроде бы не только из исходников состоит, там еще и либина нужна?

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

Если имеется в виду «string of bytes» - то нет.

vector сам по себе является массивом. Конкатенировать векторы тоже достаточно просто.

KennyMinigun ★★★★★ ()
Ответ на: комментарий от Bad_ptr

С++ не поддерживает интроспецию, так что все поля приходится обходить вручную. К тому же они разного размера со всеми вытекающими.
К тому же я не так уж и много этих += понаписал, но я вообще ленивый, а когда приходится делать монотонную работу, то становлюсь суперленивым. Так что пойду писать свою функцию.

P.S. за max_size отдельное спасибо. Полезная фишка.

trex6 ★★★★★ ()
Ответ на: комментарий от KennyMinigun

Не, мне там сериализовать то надо - board для крестиков/ноликов. Ради этого впиливать буст в андроид-приложение - это слишком.

trex6 ★★★★★ ()
typedef struct {
  char *p;
  int len;
  int cons;
} buff_t;

#define INITB(b,p,l) \
  ((buff_t)(b)).p=((char *)(p)); \
  len=(l);cons=0


#define EATB(b,dst,num) \
  assert((b).cons+num<(b).len); \
  memmove((dst),((b).p+(b).cons),(num)); \
  (b).cons+=(num)
  

шото типа такого.

Jetty ★★★★★ ()
Ответ на: комментарий от trex6

Вот эти вот += уже писать поднадоело.

А написать свою функцию из 2-3 строк тебе не позволяют?

tailgunner ★★★★★ ()

Что-то мне подсказывает, что тебе следует написать storage класс для этих действий. Или хотя бы inline-функию или макрос, как уже заметили.

auto12884835 ()
Ответ на: комментарий от trex6

С++ не поддерживает интроспецию, так что все поля приходится обходить вручную. К тому же они разного размера со всеми вытекающими.

Есть два культурных пути: либо как в boost::serialization (при каждом классе оператор, перечисляющий его поля), либо как в google protobuffers (кодогенерация из специального языка в c++). Ну и еще третий путь: с опорой на парсер компилятора (парсить c++ код в xml, а из xml генерировать c++ код сериализаторов).

Manhunt ★★★★★ ()
Последнее исправление: Manhunt (всего исправлений: 2)
Ответ на: комментарий от Boy_from_Jungle

там есть поддержка C/C++ через NDK

Разве это не приведет к тому, что нужно будет скомпилировать программу под каждое из зоопарка андройд-устройств?

Manhunt ★★★★★ ()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

boost::serialization? Данунах!!!

Юзать либу, в которой почти в каждой новой версии ломают совместимость сериализованых данных - спасибо. А потом ипаться с линковкой нового буста и старого boost::serialization. Понарывался на это говно, теперь даже идея сериализации вручную не так дико смотрится.

Pavval ★★★★★ ()
Ответ на: комментарий от KennyMinigun

Так вот, продолжай юзать Qt. Там можно задать версию бинарного формата, а значит всё ок. А юзабельность boost::serialization с учетом этого фейла околонулевая.

Pavval ★★★★★ ()

ради сомнительной выгоды ты готов пустить бесов в проект? а ты смелый :)

вообще, чего ты плачешь - напиши свой аллокатор, он тебе во время memcpy ещё и калинкумалинку танцевать будет, какие проблемы?

shty ★★★★★ ()

а зачем, вообще, память по адресному пространству гонять?

а зачем массив, когда есть список?

как с фрагментацией памяти борешься?

dimon555 ★★★★★ ()
Ответ на: комментарий от dimon555

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

Reset ★★★★★ ()
Ответ на: комментарий от trex6

Вот эти вот += уже писать поднадоело.

Оберни доступ к буферу в какой-нибудь ЧтоТоТамStream, в нём и делай +=.

O02eg ★★★★★ ()
Ответ на: комментарий от shty

1. Сейчас у меня такой период, стараюсь использовать только уже готовые библиотеки. Пытаюсь вообще не выходить за рамки std.

2. Предложите ваш вариант сериализации объекта, у которого есть 10 полей разного размера и типа (в том числе некоторые из них массивы) без портянки (для каждого поля один memcpy и один += ).

trex6 ★★★★★ ()
Ответ на: комментарий от anonymous

Спасибо тебе, добрый анонимус. Судя по man, именно это я и искал.

trex6 ★★★★★ ()
Ответ на: комментарий от dimon555

Какая фрагментация? Этот массив потом отдается андроидовскому savedState. Как мне тут поможет список - не очень понятно.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

С++ не поддерживает интроспецию, так что все поля приходится обходить вручную.

А помочь ему в этом? Создать вспомогательную структуру, описывающую сериализируемые данные, которая и при десериализации будет использоваться. Тогда сам процесс копирования будет простым. И при изменениях нужно будет просто отредактировать структурку, но не трогать код цикла.

gag ★★★★★ ()
Ответ на: комментарий от gag

По уму так и нужно было делать, но надо бы было очень долго думать над подобной структурой, чтобы она потом могла использоваться и в наследниках тоже. В итоге я решил сделать все по-быстрому, кода получилось около 20 строчек (сериализация/десериализация).

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

void *heap_addr = sbrk((ptrdiff_t) 0)

/*здесь многочисленные maloc, free, new, delete*/

void *heap_end = sbrk((ptrdiff_t) 0)

ну и потом первый адрес передаёшь

куча все дела.

p.s. не знаю что такое savedState и андроид

dimon555 ★★★★★ ()
Ответ на: комментарий от trex6

1. Сейчас у меня такой период, стараюсь использовать только уже готовые библиотеки. Пытаюсь вообще не выходить за рамки std.

В итоге я решил сделать все по-быстрому, кода получилось около 20 строчек (сериализация/десериализация).

Да, мне тоже часто не хочется брать целую библиотеку, если кода самому писать не много. А вот чего хочется, так это, чтобы к библиотеке была документация, как в кратце они реализовали функционал. Чтобы свои 20 строчек имели сравнительное качество, но в них был только мой частный случай. Тогда получаем 2в1: проверенное решение + без доп. зависимостей.

gag ★★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

android.application.savedState

Надо его туда правильно сохранить, а потом еще и правильно его оттуда считать.

trex6 ★★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

Пользователь играет, затем свернул приложение, назапускал кучу софта, моя игра была убита. Потом пользователь решил завершить партию.

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

Вроде бы все верно.
Или я где-то ошибся?

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

Как непоноценный вариант, можно сказать чтобы приложение не убивалось из памяти, те оно может быть убито, но в самом крайнем случае
Только чесно говоря сейчас не помню что нужно для этого дописать

Boy_from_Jungle ★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

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

А программистов, которые вместо того, чтобы осиливать сериализацию/десериализацию занимаются подобным рукоблудством, необходимо вышвыривать из профессии на мороз.

Без права апелляции.

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

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

Boy_from_Jungle ★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

Нет, только когда ОС пришлет мне запрос на сохранение. Она его как раз и присылает, когда собирается с приложением сделать что-нибудь нехорошее =)

trex6 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.