在堆上从二进制数组转换为多维数组

时间:2010-07-08 03:04:45

标签: c++ c multidimensional-array heap binaryfiles

我目前正在使用二进制文件来快速访问存储在多维数组中的自定义对象,这些数据作为对象数组保存到文件中。到目前为止,从文件读取并没有太大问题,因为我已经将数组读入堆栈中的相同对象数组。它看起来像这样:

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 个答案:

答案 0 :(得分:1)

在我看来,使用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指针。

答案 1 :(得分:0)

我不认为您使用的解决方案在一般情况下会起作用;现代操作系统利用堆随机化,因此并不总是可以跨程序的多次运行声明相同的虚拟地址空间。

如果您的任何存储对象包含指针,则在加载到其他虚拟拓扑中时它们会悬挂。

您是否尝试将对象序列化为适当的磁盘格式而不是仅编写二进制blob?

答案 2 :(得分:0)

我编写非托管代码已经很久了,我现在甚至都记不起语法了。有一种方法可以分配一个连续的内存块,并能够转换为多维数组。如果您一次性分配所需的全部内容,则使每个元素指向该块中的相关位置。 (对语法/代码损坏表示抱歉)。

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))
}