这是我的结构
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存储在文件中并将其编入索引以供进一步分析。
答案 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 。你不能希望只为你拥有全部记忆。所以你的程序会像疯了一样使用虚拟内存。您 想到一种仅部分存储元素的方法,或者您的程序将遇到很大麻烦。