C++:使用指针存储/访问大对象以避免内存不足

Posted

技术标签:

【中文标题】C++:使用指针存储/访问大对象以避免内存不足【英文标题】:C++: Storing/accessing large objects with pointers to avoid running out of memory 【发布时间】:2015-02-18 17:27:07 【问题描述】:

我有一个 C++ 应用程序需要同时将几个非常大的 unordered_map 加载到内存中,结果我在运行时用完了 堆栈空间 堆空间(在一些大的 unordered_maps 已经加载之后):

granger(34190, 0x7fff73062300) malloc: *** mach_vm_map(size=8949833580846596096) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
libc++abi.dylib: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
[1]    34488 abort      ./granger

似乎一个潜在的解决方案是将这些大型数据结构中的一些保留在堆中 存储为指针,这样我就可以避免内存不足。 这个逻辑正确吗?

如果是,这是我尝试实施更改时遇到的下一个问题:

当我声明要保留在堆中的 unordered_maps 时,我使用指针(例如;unordered_map< string,vector<string> > *allMeds = mapAllMeds(ALL_MEDS_FILE); mapAllMeds 函数创建大的 unordered_map,我假设它将它返回给名为 *allMeds 的指针。还没有问题 当我尝试访问 *allMeds(或我定义为指针的任何其他 unordered_maps)中的元素时,我收到错误 no viable overloaded operator[] for type 'unordered_map<string, vector<string> > *

编辑:第三个要点的示例代码:vector<string> medsForPatient = allMeds[aPatient.getDeid()]; 返回我上面描述的错误。

这是否意味着当我尝试访问由指针定义的无序映射中的键/值对时,我不能使用普通的[] 运算符?如果不是,可以改用什么解决方法?

编辑 2:好的,所以 cmets 告诉我我的堆空间用完了,而不是堆栈空间,但这根本不能解决我的问题:我可以采取什么方法来获得所有的数据结构同时存入内存而不会耗尽可寻址的内存空间?

编辑 3:这是应用程序在运行时崩溃的函数:

unordered_map<string,string> makeMedSynonyms() 
    unordered_map<string,string> medSynonymsMap;
    string delimiters = "|";
    ifstream ifs(MED_SYNONYMS_FILE);
    string line;
    while(std::getline(ifs, line)) 
        vector<string> medSynVec;
        string::size_type lastPos = line.find_first_not_of(delimiters, 0);
        string::size_type pos = line.find_first_of(delimiters, lastPos);
        while(string::npos != pos || string::npos != lastPos) 
            medSynVec.push_back(line.substr(lastPos, pos - lastPos));
            lastPos = line.find_first_not_of(delimiters, pos);
            pos = line.find_first_of(delimiters, lastPos);
        
        medSynonymsMap[medSynVec[0]] = medSynVec[1];
    
    return medSynonymsMap;

【问题讨论】:

你用完了堆内存,而不是栈内存。 你不能使用 [] 因为你得到的是指向 unordered_map 的指针,而不是 unordered_map 类型的对象。您需要先取消引用该指针:vector &myVec = (*allMeds)[myString]; @JDRomano2 size=8949833580846596096 你知道那是多少内存吗?那是 8139826 太字节,你的程序肯定有问题。除非你为 NASA 或 NBA 工作 @JDRomano2 我同意斯拉瓦的观点。考虑到size 的高得离谱的值,您的程序有问题很可能 内存相关。也许你的对象已经失效了,而你仍然有指向它们的指针,从而产生了疯狂的值? @JDRomano2 - medSynonymsMap[medSynVec[0]] = medSynVec[1]; 你没有检查medSynVec 中是否至少有 2 个条目。如果条目数 【参考方案1】:

函数的一个问题是:

  medSynonymsMap[medSynVec[0]] = medSynVec[1];

您没有检查medSynVec 是否至少有 2 个条目。如果条目数

【讨论】:

以上是关于C++:使用指针存储/访问大对象以避免内存不足的主要内容,如果未能解决你的问题,请参考以下文章

C++ 优先队列push()时,出现内存不足,怎么办,能又啥办法解决吗

C++中内存分配问题

C++读懂指针与内存

zList一个块状链表算法可以申请和释放同种对象指针,对于大数据量比直接new少需要差不多一半内存

C++内存重叠

动态内存和智能指针