Vector有2亿件商品

时间:2013-09-26 14:07:19

标签: c++ list vector

这是我的结构

struct Node
{
 int chrN;
 long int pos;
 int nbp;
 string Ref;
 string Alt;
};

填充我通过文件读取的结构并将我的兴趣变量解析为结构,然后将其推回到vectore。问题是,有大约2亿个项目,我应该将它们全部保留在内存中(进一步的步骤)!但是在推回了50万个带有bad_allocation错误的节点之后程序就终止了。

terminate called after throwing an instance of 'std::bad_alloc'
what():  std::bad_alloc
四处搜索给我的想法我记忆犹新!但顶部的输出显示%48(终止发生时)

可能有用的其他信息: 我设置堆栈限制无限制和 我正在使用Ubuntu x86_64 x86_64 x86_64 GNU / Linux和4Gb RAM。

欢迎任何帮助。

更新

首先从向量切换到列表,然后将每个~500Mb存储在文件中并将其编入索引以供进一步分析。

5 个答案:

答案 0 :(得分:4)

矢量存储是连续的,在这种情况下,200 mio *需要struct字节的大小。对于结构中的每个字符串,可能需要另一个小分配来保存字符串。总而言之,这不适合您的可用地址空间,并且没有(非压缩)数据结构将解决这个问题。

向量通常会以指数方式增加其支持能力(这会分摊push_back的成本)。因此,当您的程序已经使用了大约一半的可用地址空间时,向量可能会尝试将其大小加倍(或添加50%),这会导致bad_alloc并且它没有释放先前的缓冲区,因此最终记忆似乎只有48%。

答案 1 :(得分:2)

该节点结构最多消耗44个字节,加上实际的字符串缓冲区。它们中有2亿个不适合4 GB。

您不需要立即将整个数据集保存在内存中。

答案 2 :(得分:0)

由于向量必须将所有元素存储在连续内存中,因此在使用完整可用RAM之前,更有可能耗尽内存。

尝试使用std :: list并查看是否可以保留所有项目。您将无法随机访问这些元素,但这是您最有可能需要处理的权衡。

std :: list可以更好地利用RAM的自由片段,因为与向量不同,它不会尝试将元素彼此相邻存储。

答案 3 :(得分:0)

根据数据类型的大小,我猜,你使用的结构至少是4 + 8 + 4 + 2 + 2 = 20字节长。如果您有2亿个数据字段,那么这将是大约3,8 GB的数据。不确定你从顶部读到了什么,但这接近你的记忆限制。

正如LatencyMachine所指出的那样,这些项必须在一个连续的内存块中,这将是困难的(字符串内存可以在其他地方,但我总结的两个字节必须在向量中)。

初始化具有正确大小的向量可能有助于避免重新分配。

答案 4 :(得分:0)

如果你看一下这段代码:

#include <iostream>
using namespace std;
struct Node
{
 int chrN;
 long int pos;
 int nbp;
 string Ref;
 string Alt;
};
int main() {
    // your code goes here
    cout << sizeof(Node) << endl;
    return 0;
}

它在ideone上生成的结果你会发现你的结构大小即使字符串是空的而且在32位计算机上也是20.因此200 * 10^6倍这个大小恰好是4GB 。你不能希望只为你拥有全部记忆。所以你的程序会像疯了一样使用虚拟内存。您 想到一种仅部分存储元素的方法,或者您的程序将遇到很大麻烦。