приведение из двоичного к многомерному массиву в куче - PullRequest
2 голосов
/ 08 июля 2010

В настоящее время я использую двоичные файлы для быстрого доступа к пользовательским объектам, хранящимся в многомерных массивах, которые сохраняются в файл в виде массивов объектов.до сих пор чтение из файла не было слишком большой проблемой, так как я считывал массив в идентичный массив объектов в стеке.это выглядит примерно так:

Foo foo[5][10];
ifstream infile("foofile.dat",ios::in|ios::binary);
infile.read((char*)&foo, sizeof Foo);

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я все больше храню большие объемы данных и переполняю свой стек при создании массива локальных объектов.решение тогда, казалось бы, создало массив локальных объектов в куче, и я не уверен, как отформатировать его так, чтобы я мог приводить его непосредственно из char *.вот как я бы выделил в куче:

Foo (*foo)[1000] = new Foo [500][1000];

однако, похоже, это неправильный формат, если я хочу привести ко всему массиву.например, если я попытаюсь сделать следующее, это не сработает:

ifstream infile("foofile.dat",ios::in|ios::binary);
infile.read((char*)(*foo), (sizeof Foo * 500 * 1000));  //or below
infile.read((char*)(&foo), (sizeof Foo * 500 * 1000));  //or below
infile.read((char*)(foo), (sizeof Foo * 500 * 1000));   //or below

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

Большое спасибо, Джим

Ответы [ 3 ]

1 голос
/ 08 июля 2010

По моему мнению, здесь нет особого смысла использовать механизмы C ++ для выделения / освобождения, так как вы полностью перезаписываете данные чтением.Так что не делайте new / delete вещи.Ваш каст (char*) на самом деле reinterpret_cast< char* >.Почему бы просто не использовать malloc с правильным размером?

typedef Foo largeFoo[500][1000];
largeFoo* data = reinterpret_cast< largeFoo* >(malloc(sizeof largeFoo));

Затем прочитайте это (снова с reinterpret_cast).Для удобства вы можете использовать псевдоним вашего указателя на ссылку.

largeFoo& foo = *data;

, чтобы весь оставшийся код мог оставаться таким же, как в стековой версии, с только free указателем в конце.

0 голосов
/ 08 июля 2010

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

void* ptr = malloc (void*)(sizeof(Foo) * 500 * 1000);
Foo** foo = (Foo**)ptr;
for (int i=0;i<500;i++) {
    foo[i] = (Foo*)(ptr+500*i*sizeof(Foo))
}
0 голосов
/ 08 июля 2010

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

Если какой-либо из ваших сохраненных объектов содержит указатели, они будут зависать при загрузке в другую виртуальную топологию.

Вы пытались сериализовать свои объекты в надлежащий формат на диске вместо того, чтобы просто записать двоичный двоичный объект?

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