简体   繁体   English

.. Microsoft C ++异常的未处理异常:内存位置处的std :: bad_alloc

[英]Unhandled exception at .. Microsoft C++ exception: std::bad_alloc at memory location

I have a large vector (mainvect) of struct info objects (about 8million element), and I want to remove duplicates, the struct consist of pid, and uid . 我有一个结构信息对象(约800万个元素)的大向量(mainvect) ,并且我想删除重复项,该结构由pid和uid组成。

 struct info
 {
    int pid;
    string uid;

 }

I have another vector ( vect1 ) which contain information of each pid and its occurrence in mainvect (its help in search specific indices not all the main vect) size of vect1 is 420k elements 我有另一个向量( vect1 ),其中包含每个pid的信息及其在mainvect中的出现(它有助于搜索特定索引,而不是所有主要vect)vect1的大小为420k个元素

struct pidInfo
 {
    int pid;
    int numofoccurence;
}

I want to store unqiue elements in mainvect in vect2 . 我想将unqiue元素存储在vect2的mainvect中

 .
 .
// sort mainvect based on pid
sort(mainvect.begin(), mainvect.end(), sortByPId());

int start = 0;
int end = 0;
vector <string> temp;  // to store uids with a specific pid 

for (int i = 0; i < vect1.size(); i++)
{
   end = end + vect1[i].numofoccurence;

    for (int j = start; j < end; j++)
    {
        temp.push_back(mainvect[j].uid);
    }

    start = start + vect1[i].numofoccurence;

    // remove duplicate uid 
    sort(temp.begin(), temp.end());
    temp.erase(unique(temp.begin(), temp.end()), temp.end());

    // push remaining unique uids 
    for (int k = 0; k < temp.size(); k++)
    {
        info obb;
        obb.pid = vect1[i].pid;
        obb.uid = temp[k];
        vect2.push_back(obb);
    }

    // empty the temp vector to use in next i iteration
    temp.erase(temp.begin(), temp.end());

}
 .
 .

But when I run the code, it gave me exception as shown in the following figure 但是当我运行代码时,它给了我异常,如下图所示 在此处输入图片说明

You are running out of memory. 您的内存不足。 There are few things you can do: 您可以执行以下几项操作:

  1. You are building 32-bit program on Windows. 您正在Windows上构建32位程序。 This means you have only 2 GB of RAM available, regardles of how much physical memory have on your machine. 这意味着您只有2 GB的RAM,这取决于计算机上有多少物理内存。 You should build your program for 64-bit architecture to get access to all RAM you have. 您应该为64位体系结构构建程序,以访问您拥有的所有RAM。 To do this you need to create of new configuration for your project with platform set to x64 . 为此,您需要为平台设置为x64项目创建新配置。
  2. You should be smarter about using your memory. 您应该更聪明地使用内存。 The quickest thing you can do is to replace std::vector with std::dequeu for large vectors. 您可以做的最快的事情是将std::vector替换为std::dequeu以获得较大的向量。

The problem with std::vector is that every time it grows it allocates a new memory chunk and copies all data. std::vector的问题在于,每增长一次,它就会分配一个新的内存块并复制所有数据。 MSVC implementation you are using grows vector by factor of 1.5 each time. 您正在使用的MSVC实现每次将矢量增加1.5倍。 So if vector takes 1 GB of memory, next time it resizes it will try to allocate 1.5 GB, taking 2.5 GB of RAM in total while resizing is in progress. 因此,如果vector占用1 GB的内存,则下次调整大小时,它将尝试分配1.5 GB,在调整大小的同时总共占用2.5 GB的RAM。

Implementations of std::deque will usually allocate memory in smaller chunks, so it will have less problem with resizing. std::deque实现通常将在较小的块中分配内存,因此在调整大小方面将减少问题。

Another thing you should pay attention to is std::string . 您还应注意的另一件事是std::string MSVC implementation uses SSO (Small-String-Optimization) . MSVC实现使用SSO(小字符串优化) Every instance of std::string` afair takes 32 bytes on x86. Every instance of std :: string` afair Every instance of在x86上占用32个字节。 So every element in your 8 million elements vector might or might not be wasting this memory. 因此,您800万个元素向量中的每个元素可能或可能不会浪费此内存。

Depending on how much time you want to spend on your program, you might want to learn about memory-mapped files . 根据您要花多少时间在程序上,可能要了解有关内存映射文件的信息

I think you actually have algorithm problem. 我认为您实际上有算法问题。 On each iteration you are sorting and leaving only unique elements in temp vector. 在每次迭代中,您都将排序并在temp向量中仅保留唯一元素。 But with this approach each iteration will add more and more duplicates into vect2 . 但是,使用这种方法,每次迭代都会向vect2添加越来越多的重复vect2 So you should sort and leave only unique elements in vect2 as well. 因此,您也应该在vect2仅排序并保留唯一元素。 Actually it would be probably better to utilize std::set instead of temp and vect2 . 实际上,最好使用std::set代替tempvect2

Another suggestion would be to utilize a better storage for uid if it has some sort of fixes-length format, such as GUID. 另一个建议是,如果它具有某种固定长度格式(例如GUID),则可以为uid使用更好的存储。

As state above, you are running out of memory. 如上所述,您的内存不足。 If you really have so many elements, it may be a sensible idea to look into a small database, like sqlite. 如果您确实有这么多元素,那么研究小型数据库(例如sqlite)可能是一个明智的主意。

But since the question is about C++ standard containers, you are approaching the problem a bit hamfisted. 但是由于问题是关于C ++标准容器的,因此您遇到的问题有些牵强。 You are doing many unnecessary sorts and loops. 您正在执行许多不必要的排序和循环。 Not only riddled with bugs, your algorithm is at least O(n^3) 不仅布满错误,而且算法至少为O(n ^ 3)

Why not use one of the already sorted containers, for example std::map? 为什么不使用已经排序的容器之一,例如std :: map? You can deduplciate a list like so: 您可以像这样对列表进行重复数据删除:

std::vector<info> input;

// copy into map
std::map<int, info> tmp;
for (info& i : mainvect) {
  tmp[i.pid] = i;
}

// copy back out
std::vector<info> output(tmp.size());
std::transform(tmp.begin(), tmp.end(), output.begin(), [] (const std::pair<int, info>& p) {
    return p.second;
});

Not only is the code cleaner, it runs at O(n + ln(n)). 代码清除器不仅运行在O(n + ln(n))。 Or, skip the second step and use an std::map or std::set for the data in the first place. 或者,跳过第二步,首先使用std :: map或std :: set作为数据。

Also if you handle a huge number of items, you don't want to use a std::vector. 同样,如果您处理大量项目,则不希望使用std :: vector。 The key problem is that the memory for the vector needs to be one continuous piece of memory. 关键问题是向量的内存需要是一个连续的内存。 You may want to use a deque or a list. 您可能要使用双端队列或列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 [内存分配问题]未处理的异常:Microsoft C ++异常:内存位置处的std :: bad_alloc - [Memory allocation problem]Unhandled exception: Microsoft C++ exception: std::bad_alloc at memory location Microsoft C ++异常:cin命令导致内存位置处的std :: bad_alloc - Microsoft C++ exception: std::bad_alloc at memory location cause by cin command C++ API 未处理异常:Microsoft C++ 异常:std::bad_alloc - C++ API unhandled exception: Microsoft C++ exception: std::bad_alloc Milestone2.exe中0x7700C42D的未处理异常:Microsoft C ++异常:内存位置0x003EF5DC的std :: bad_alloc - Unhandled exception at 0x7700C42D in Milestone2.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x003EF5DC 0x771515ee处的未处理异常Microsoft C ++异常:内存位置为0x0049f904的std :: bad_alloc - Unhandled exception at 0x771515ee Microsoft C++ exception: std::bad_alloc at memory location 0x0049f904 内存位置的未处理异常bad_alloc - Unhandled exception bad_alloc at memory location C ++未处理的异常:std :: bad_alloc - C++ Unhandled Exception: std::bad_alloc 向量存储限制的向量-获取“ Microsoft C ++异常:内存位置0x0031650C处的std :: bad_alloc。”错误 - Vector of vector storage limitations - getting “Microsoft C++ exception: std::bad_alloc at memory location 0x0031650C.” error Microsoft C异常:内存位置0x0017F5E0处的std :: bad_alloc - Microsoft C exception: std::bad_alloc at memory location 0x0017F5E0 C++ bad_alloc 在 memory 位置异常 - C++ bad_alloc at memory location Exception
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM