ALLOC不好时,抛出 [英] Bad alloc is thrown

查看:166
本文介绍了ALLOC不好时,抛出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到一个'bad_alloc尝试与提升管理的共享内存来工作。我从他们的快速指南急躁复制升压例子,结合我自己的变化。 MY code是下面,我已经注释掉的例子的东西,自己写了下面。我也把一些调试和测试的东西。

有没有人有什么想法?任何帮助是极大AP preciated!

-M

 的#include<升压/间/ managed_shared_memory.hpp>
#包括LT&;升压/间/集装箱/ map.hpp>
#包括LT&;升压/间/分配器/ allocator.hpp>
#包括LT&;升压/间/集装箱/ string.hpp>
#包括LT&;升压/间/ exceptions.hpp>的#include<功能>
#包括LT&;实用>
#包括LT&;&iostream的GT;
#包括LT&;串GT;#定义SPACE_NAMEMySharedMemorydfgdfhgd
空间std {
}诠释的main()
{使用空间boost ::进程间;
//删除建设和破坏共享内存结构shm_remove
{
    shm_remove(){shared_memory_object ::删除(SPACE_NAME); }
    〜shm_remove(){shared_memory_object ::删除(SPACE_NAME); }
}卸妆;的typedef INT关键字类型;
TYPEDEF的boost ::进程间:: managed_shared_memory ::分配器<&烧焦GT; ::类型char_allocator;
// typedef的提高::进程间::分配器<焦炭,升压::进程间:: managed_shared_memory :: segment_manager> char_allocator;
TYPEDEF的boost ::进程间:: basic_string的<焦炭,的std :: char_traits<焦炭>中char_allocator> shm_string;结构certificateStorage {
    INT certificate_id;
    certificateStorage(INT _certificate_id,为const char * _certificate,为const char * _key,常量char_allocator&安培;人):
    certificate_id(_certificate_id)
    {}
};//注意地图<关键,MappedType>的value_type为的std ::对< const的重点,MappedType>中
//所以分配器必须分配的对。//的typedef的std ::对< const int的,浮动>值类型;
的typedef的std ::对< const int的,certificateStorage> certValueType;
// typedef的分配器<值类型,managed_shared_memory :: segment_manager> ShmemAllocator;
typedef的分配器< certValueType,提高::进程间:: managed_shared_memory :: segment_manager> certShmemAllocator;
// typedef的地图和LT;关键字类型,MappedType,性病::少<关键字类型>中ShmemAllocator> MyMap中;
typedef的地图和LT;关键字类型,certificateStorage,性病::少<关键字类型>中certShmemAllocator> certSHMMap;
// typedef的提高::进程间::地图<关键字类型,INT的std ::以下<关键字类型>中certShmemAllocator> certSHMMap;性病::法院LT&;< \\ n \\ n \\ n起始程序\\ n \\ n \\ n;//共享内存前端,能够构造对象
//与C字符串有关。删除previous共享内存的名称
//被使用并在指定的地址创建存储器段和初始化资源const int的numentries = 20;
为const char *的ElementName =MyMap中;
INT大小= sizeof的(certificateStorage)* numentries + 1000;
性病::法院LT&;< SHM大小为<<尺寸和LT;< 字节的\\ n;
INT runningsize = 0;
尝试{
    //这个保持不变
    managed_shared_memory shm_segment
    (create_only
    ,SPACE_NAME //段名
    ,尺寸);    certSHMMap * MyMap中;    //初始化共享内存STL兼容分配器
    // ShmemAllocator alloc_inst(segment.get_segment_manager());
    certShmemAllocator alloc_inst(shm_segment.get_segment_manager());
    char_allocator CA(shm_segment.get_allocator<焦炭>());    的for(int i = 0; I< numentries;我++){        尝试{
            // MyMap中* MyMap中=
            // segment.construct< MyMap中>(MyMap中)//对象名称
            //(性病::少< INT>()//首先构造函数参数
            //,alloc_inst); //第二个参数的构造函数            MyMap中= shm_segment.construct< certSHMMap>(的ElementName)
            (性病::少< INT>()
            ,alloc_inst); //对象名称
        }
        赶上(升压::进程间:: interprocess_exception&安培;除息){
            性病::法院LT&;< 证书元素已经存在。            尝试{
                MyMap中= shm_segment.find< certSHMMap>(的ElementName)。首先, //对象名称
                 性病::法院LT&;< 读取现有的指针\\ n;
            }
            赶上(升压::进程间:: interprocess_exception&安培;除息){
                性病::法院LT&;< \\ nCertificates对象不会加载\\ n;
                MyMap中= shm_segment.find< certSHMMap>(的ElementName)。首先, //对象名称
            }
        }        certificateStorage thisCert(ⅰ,,,加利福尼亚州);
         性病::法院LT&;< 创建的对象\\ n;
        mymap->插入(certValueType(I,thisCert));
         性病::法院LT&;< 插入的对象。<< I<<大小<<的sizeof(thisCert)LT;< \\ n;
         runningsize + = sizeof的(thisCert);
         性病::法院LT&;< SHM当前大小为<< runningsize<< /<<大小和LT;< \\ n;
    }    性病::法院LT&;< \\ n \\ nDone插入\\ n起始输出\\ n;
    / *
        在地图//插入数据
        的for(int i = 0; I< 100; ++ I){
        mymap->插入(性病::对< const int的,浮动>(I,(浮点)(I * I)));
        }        的for(int i = 0; I< 100; ++ I){
        性病::法院LT&;< 关键:<< I<< 值:<< mymap->对于(I)所述;&下; \\ n;        mymap->插入(性病::对< const int的,浮动>(I,(浮点)(一* 2)));
    } * /
    的for(int i = 0; I< numentries;我++){        尝试{
            MyMap中= shm_segment.construct< certSHMMap>(的ElementName)(的std ::以下< INT>(),alloc_inst); //对象名称
        }
        赶上(升压::进程间:: interprocess_exception&安培;除息){
            性病::法院LT&;< 证书元素已经存在\\ n;            尝试{
                MyMap中= shm_segment.find< certSHMMap>(的ElementName)。首先, //对象名称
            }
            赶上(升压::进程间:: interprocess_exception&安培;除息){
                性病::法院LT&;< 证书对象不会加载\\ n;
                MyMap中= shm_segment.find< certSHMMap>(的ElementName)。首先, //对象名称
            }
        }
        certificateStorage TMP = mymap->对于(ⅰ);
        性病::法院LT&;< 最关键的是:<< I<< 和值是:<< tmp.certificate_id;
    }
}
赶上(升压::进程间:: interprocess_exception&安培;除息){
    性病::法院LT&;< \\ n SHM空间不会加载不会加载\\ n;
    性病::法院LT&;< \\ n原因:<< ex.what()&所述;&下; \\ n;
}
shared_memory_object ::删除(SPACE_NAME);
返回0;

}

这是我的程序的输出...

 启动该程序。
SHM大小为1080字节
创建的对象。
插入的对象。 0大小为4
SHM当前大小为一千○八十○分之四
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 1大小为4
SHM当前大小为一千○八十○分之八
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 2大小为4
SHM当前大小为一千○八十○分之十二
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 3大小为4
SHM当前大小为一千零八十分之十六
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 4大小为4
SHM当前大小为一千○八十〇分之二十〇
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 5大小为4
SHM当前大小为一千○八十○分之二十四
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 6大小为4
SHM当前大小为1080分之28
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 7大小为4
SHM当前大小为一千○八十〇分之三十二
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 8大小为4
SHM当前大小为一千零八十零分之三十六
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 9大小为4
SHM当前大小为一千零八十零分之四十〇
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 10大小为4
SHM当前大小为一千零八十分之四十四
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 11大小为4
SHM当前大小为一千零八十零分之四十八
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 12大小为4
SHM当前大小为一千零八十分之五十二
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 13大小为4
SHM当前大小为一千零八十零分之五十六
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 14大小为4
SHM当前大小为一千零八十零分之六十○
证书元素已经存在。获取现有的指针。
创建的对象。
插入的对象。 15大小为4
SHM当前大小为一千零八十零分之六十四
证书元素已经存在。获取现有的指针。
创建的对象。 SHM空间不会加载不会加载 理由:升压::进程间:: bad_alloc


解决方案

看来你只是运行内存。你可能有理由,你不应该因为个人的分配不占用的空间量。

但内存碎片可以做到这一点:如果有足够的'填充'或'架空'的共享内存对象,您可以用完的连续分配的的空间。

无论哪种,存储你的数据在pre-分配的载体(例如),或使用的聪明间分配算法之一:

要解决它在这种情况下最简单的方法似乎是只是让共享内存区域的两倍大(最小尺寸是大多数系统上4K内存页,反正)。

我只是用 2 *尺寸和测试运行完成。

更新/修复

我刚刚证实,确实做的事情向量方法是更有效:更换的std ::地图通过升压的 flat_map 让你矢量存储。

的最大区别在于,在图中的每个节点动态分配,招致固定的开销,线性消耗可用的存储器

观察


  • 有相当的初始开销,耗时320个字节发生什么意外了。

  • flat_map ,你也保留了矢量能力达阵,你看,你可以赢得一点点额外的存储效率。

上面的曲线图由下面程序的输出创建的。查找调用 get_free_memory()。要切换地图实现,只需改变 0#如果#如果1 。的(注意:我如何清理一些code,这是不必要的重复和使用流量控制例外)

 的#include<升压/间/ managed_shared_memory.hpp>
#包括LT&;升压/间/集装箱/ map.hpp>
#包括LT&;升压/间/分配器/ allocator.hpp>
#包括LT&;升压/间/集装箱/ string.hpp>
#包括LT&;升压/间/集装箱/ flat_map.hpp>
#包括LT&;升压/间/ exceptions.hpp>的#include<功能>
#包括LT&;实用>
#包括LT&;&iostream的GT;
#包括LT&;串GT;#定义SPACE_NAMEMySharedMemory诠释的main()
{
    使用空间boost ::进程间;
    //删除建设和破坏共享内存    结构shm_remove
    {
        shm_remove(){shared_memory_object ::删除(SPACE_NAME); }
        〜shm_remove(){shared_memory_object ::删除(SPACE_NAME); }
    }卸妆;    的typedef INT关键字类型;
    TYPEDEF的boost ::进程间:: managed_shared_memory ::分配器<&烧焦GT; ::类型char_allocator;
    // typedef的提高::进程间::分配器<焦炭,升压::进程间:: managed_shared_memory :: segment_manager> char_allocator;
    //类型定义的boost ::进程间:: basic_string的<焦炭,的std :: char_traits<焦炭>中char_allocator> shm_string;    结构certificateStorage {
        INT certificate_id;
        certificateStorage(INT _certificate_id,为const char * _certificate,为const char * _key,常量char_allocator&安培;人):
            certificate_id(_certificate_id)
        {}
    };#如果0 // STL
    的typedef的std ::对< const int的,certificateStorage> certValueType;
    typedef的分配器< certValueType,提高::进程间:: managed_shared_memory :: segment_manager> certShmemAllocator;
    typedef的地图和LT;关键字类型,certificateStorage,性病::少<关键字类型>中certShmemAllocator> certSHMMap;
#else伪// FLAT_MAP
    的typedef的std ::对< INT,certificateStorage> certValueType;对于flat_map //不是const的关键
    typedef的分配器< certValueType,提高::进程间:: managed_shared_memory :: segment_manager> certShmemAllocator;
    TYPEDEF提振::容器:: flat_map<关键字类型,certificateStorage,性病::少<关键字类型>中certShmemAllocator> certSHMMap;
#万一    性病::法院LT&;< \\ n \\ n \\ n起始程序\\ n \\ n \\ n;    const int的numentries = 20;
    为const char *的ElementName =MyMap中;
    INT大小= sizeof的(certificateStorage)* numentries + 1000;
    INT runningsize = 0;    性病::法院LT&;< SHM大小为<<尺寸和LT;< 字节的\\ n;    尝试{
        managed_shared_memory shm_segment(create_only,SPACE_NAME / *段名* /,大小);        certShmemAllocator alloc_inst(shm_segment.get_segment_manager());
        char_allocator CA(shm_segment.get_allocator<焦炭>());        certSHMMap * MyMap中= shm_segment.find_or_construct< certSHMMap>(的ElementName)
            (性病::少< INT>(),alloc_inst);        mymap->储备(numentries);        的for(int i = 0; I< numentries;我++){
            性病::法院LT&;< 自由记忆:<< shm_segment.get_free_memory()&所述;&下; \\ n;            certificateStorage thisCert(ⅰ,,,加利福尼亚州);
            性病::法院LT&;< 创建的对象\\ n;
            mymap->插入(certValueType(I,thisCert));
            性病::法院LT&;< 插入的对象。<< I<<大小<<的sizeof(thisCert)LT;< \\ n;
            runningsize + = sizeof的(thisCert);
            性病::法院LT&;< SHM当前大小为<< runningsize<< /<<大小和LT;< \\ n;
        }        性病::法院LT&;< \\ n \\ nDone插入\\ n起始输出\\ n;        的for(int i = 0; I< numentries;我++){
            certificateStorage TMP = mymap->对于(ⅰ);
            性病::法院LT&;< 最关键的是:<< I<< 和值是:<< tmp.certificate_id<< \\ n;
        }
    }
    赶上(升压::进程间:: interprocess_exception&安培;除息){
        性病::法院LT&;< \\ n SHM空间不会加载不会加载\\ n;
        性病::法院LT&;< \\ n原因:<< ex.what()&所述;&下; \\ n;
    }
}

I am getting a 'bad_alloc while trying to work with boost managed shared memory. I've copied the boost example from their quick guide for the impatient and incorporated my own changes. MY code is below, I've commented out the example stuff and wrote my own below it. I've also put in some debugging and testing stuff.

Does anyone have any ideas? Any help is greatly appreciated!

-M

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/exceptions.hpp>

#include <functional>
#include <utility>
#include <iostream>
#include <string>

#define space_name "MySharedMemorydfgdfhgd"
namespace std{


}

int main ()
{

using namespace boost::interprocess;


//Remove shared memory on construction and destruction

struct shm_remove
{
    shm_remove() { shared_memory_object::remove(space_name); }
    ~shm_remove(){ shared_memory_object::remove(space_name); }
} remover;

typedef int    KeyType;
typedef boost::interprocess::managed_shared_memory::allocator<char>::type char_allocator;
//typedef boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> char_allocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator> shm_string;

struct certificateStorage{
    int certificate_id;        
    certificateStorage( int _certificate_id, const char* _certificate, const char* _key, const char_allocator &al) :
    certificate_id(_certificate_id) 
    {}
};

//Note that map<Key, MappedType>'s value_type is std::pair<const Key, MappedType>,
//so the allocator must allocate that pair.

//typedef std::pair<const int, float> ValueType;
typedef std::pair<const int, certificateStorage> certValueType;
//typedef allocator<ValueType, managed_shared_memory::segment_manager> ShmemAllocator;
typedef allocator<certValueType, boost::interprocess::managed_shared_memory::segment_manager> certShmemAllocator;
//typedef map<KeyType, MappedType, std::less<KeyType>, ShmemAllocator> MyMap;
typedef map<KeyType, certificateStorage, std::less<KeyType>, certShmemAllocator> certSHMMap;
// typedef boost::interprocess::map<KeyType, int, std::less<KeyType>, certShmemAllocator> certSHMMap;

std::cout << "\n\n\nStarting the program.\n\n\n";

//Shared memory front-end that is able to construct objects
//associated with a c-string. Erase previous shared memory with the name
//to be used and create the memory segment at the specified address and initialize resources

const int numentries = 20;
const char* elementName = "mymap";
int size = sizeof(certificateStorage) * numentries + 1000;
std::cout << "SHM size is " <<size<< " bytes \n";
int runningsize = 0;


try{
    //this stayed the same
    managed_shared_memory shm_segment
    (create_only
    ,space_name//segment name
    ,size);   

    certSHMMap *mymap;

    //Initialize the shared memory STL-compatible allocator
    //ShmemAllocator alloc_inst (segment.get_segment_manager());
    certShmemAllocator alloc_inst (shm_segment.get_segment_manager());
    char_allocator ca(shm_segment.get_allocator<char>());

    for(int i = 0; i < numentries; i++){

        try{
            //MyMap *mymap =
            // segment.construct<MyMap>("MyMap")      //object name
            //(std::less<int>() //first  ctor parameter
            //  ,alloc_inst);     //second ctor parameter              

            mymap = shm_segment.construct<certSHMMap>(elementName)
            (std::less<int>() 
            ,alloc_inst);     //object name
        }
        catch(boost::interprocess::interprocess_exception &ex){
            std::cout << "Certificates element already exists.";

            try{
                mymap = shm_segment.find<certSHMMap>(elementName).first;   //object name
                 std::cout << " Fetching existing pointer.\n";
            }
            catch(boost::interprocess::interprocess_exception &ex){
                std::cout << "\nCertificates object wont load\n";
                mymap = shm_segment.find<certSHMMap>(elementName).first;   //object name
            }
        }

        certificateStorage thisCert(i, "", "", ca);
         std::cout << "Created object.\n";
        mymap->insert(certValueType(i, thisCert));
         std::cout << "Inserted object. " << i <<" size is " <<sizeof(thisCert)  << " \n";
         runningsize += sizeof(thisCert) ;
         std::cout << "SHM Current size is " << runningsize << " / " << size << "\n";
    }

    std::cout << "\n\nDone Inserting\nStarting output\n.";
    /*    
        //Insert data in the map
        for(int i = 0; i < 100; ++i){
        mymap->insert(std::pair<const int, float>(i, (float)(i*i)));
        }

        for(int i = 0; i < 100; ++i){
        std::cout << "Key: " << i << " Value: " << mymap->at(i) << "\n";

        mymap->insert(std::pair<const int, float>(i, (float)(i*2)));
    } */


    for(int i = 0; i < numentries; i++){

        try{
            mymap = shm_segment.construct<certSHMMap>(elementName)(std::less<int>() ,alloc_inst);     //object name
        }
        catch(boost::interprocess::interprocess_exception &ex){
            std::cout << "Certificates element already exists.\n";

            try{
                mymap = shm_segment.find<certSHMMap>(elementName).first;   //object name
            }
            catch(boost::interprocess::interprocess_exception &ex){
                std::cout << "Certificates object wont load\n";
                mymap = shm_segment.find<certSHMMap>(elementName).first;   //object name
            }
        }
        certificateStorage tmp = mymap->at(i);
        std::cout << "The key is: " << i << " And the value is: " << tmp.certificate_id;
    }
}
catch(boost::interprocess::interprocess_exception &ex){
    std::cout << "\n shm space wont load wont load\n";
    std::cout << "\n Why: " << ex.what() << "\n";


}
shared_memory_object::remove(space_name);
return 0;

}

And here is my program output...

 Starting the program.


SHM size is 1080 bytes
Created object.
Inserted object. 0 size is 4
SHM Current size is 4 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 1 size is 4
SHM Current size is 8 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 2 size is 4
SHM Current size is 12 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 3 size is 4
SHM Current size is 16 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 4 size is 4
SHM Current size is 20 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 5 size is 4
SHM Current size is 24 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 6 size is 4
SHM Current size is 28 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 7 size is 4
SHM Current size is 32 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 8 size is 4
SHM Current size is 36 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 9 size is 4
SHM Current size is 40 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 10 size is 4
SHM Current size is 44 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 11 size is 4
SHM Current size is 48 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 12 size is 4
SHM Current size is 52 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 13 size is 4
SHM Current size is 56 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 14 size is 4
SHM Current size is 60 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.
Inserted object. 15 size is 4
SHM Current size is 64 / 1080
Certificates element already exists. Fetching existing pointer.
Created object.

 shm space wont load wont load

 Why: boost::interprocess::bad_alloc

解决方案

It seems you're simply running out of memory. You might reason that you shouldn't since the individual allocations don't occupy the amount of space.

But memory fragmentation can do this: if there is sufficient 'padding' or 'overhead' with the shared memory objects, you can run out of contiguously allocatable space.

Either, store your data in a pre-allocated vector (e.g.), or use one of the smarter interprocess allocation algorithms:

The simplest way to resolve it in this instance would seem to be just making the shared memory area twice as big (minimal size is a 4K memory page on most systems, anyway).

I just used 2*size and the tests ran to completion.

Update/fixes

I've just verified that indeed doing things "the vector way" is much more efficient: replacing std::map by boost's flat_map gets you vector storage.

The big difference is that each node in a map is dynamically allocated, incurring a fixed overhead, linearly consuming available memory.

Observations

  • There's considerable initial overhead, consuming 320 bytes before anything happened.
  • with the flat_map, you also reserve the vector capacity up front, you see that you can win just a little extra storage efficiency.

The above graph was created from the output of the following program. Look for the calls to get_free_memory(). To switch map implementation, just change #if 0 into #if 1. (Note how I cleaned up some of the code that was needless repetitious and using exceptions for flow control).

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/flat_map.hpp>
#include <boost/interprocess/exceptions.hpp>

#include <functional>
#include <utility>
#include <iostream>
#include <string>

#define space_name "MySharedMemory"

int main ()
{
    using namespace boost::interprocess;
    //Remove shared memory on construction and destruction

    struct shm_remove
    {
        shm_remove() { shared_memory_object::remove(space_name); }
        ~shm_remove(){ shared_memory_object::remove(space_name); }
    } remover;

    typedef int KeyType;
    typedef boost::interprocess::managed_shared_memory::allocator<char>::type char_allocator;
    //typedef boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager> char_allocator;
    //typedef boost::interprocess::basic_string<char, std::char_traits<char>, char_allocator> shm_string;

    struct certificateStorage{
        int certificate_id;        
        certificateStorage( int _certificate_id, const char* _certificate, const char* _key, const char_allocator &al) :
            certificate_id(_certificate_id) 
        {}
    };

#if 0 // STL
    typedef std::pair<const int, certificateStorage> certValueType;
    typedef allocator<certValueType, boost::interprocess::managed_shared_memory::segment_manager> certShmemAllocator;
    typedef map<KeyType, certificateStorage, std::less<KeyType>, certShmemAllocator> certSHMMap;
#else // FLAT_MAP
    typedef std::pair<int, certificateStorage> certValueType; // not const key for flat_map
    typedef allocator<certValueType, boost::interprocess::managed_shared_memory::segment_manager> certShmemAllocator;
    typedef boost::container::flat_map<KeyType, certificateStorage, std::less<KeyType>, certShmemAllocator> certSHMMap;
#endif 

    std::cout << "\n\n\nStarting the program.\n\n\n";

    const int numentries    = 20;
    const char* elementName = "mymap";
    int size                = sizeof(certificateStorage) * numentries + 1000;
    int runningsize         = 0;

    std::cout << "SHM size is " <<size<< " bytes \n";

    try{
        managed_shared_memory shm_segment(create_only, space_name/*segment name*/, size);   

        certShmemAllocator alloc_inst (shm_segment.get_segment_manager());
        char_allocator ca(shm_segment.get_allocator<char>());

        certSHMMap *mymap = shm_segment.find_or_construct<certSHMMap>(elementName)
            (std::less<int>(), alloc_inst);

        mymap->reserve(numentries);

        for(int i = 0; i < numentries; i++){
            std::cout << "Free memory: " << shm_segment.get_free_memory() << "\n";

            certificateStorage thisCert(i, "", "", ca);
            std::cout << "Created object.\n";
            mymap->insert(certValueType(i, thisCert));
            std::cout << "Inserted object. " << i <<" size is " <<sizeof(thisCert)  << " \n";
            runningsize += sizeof(thisCert) ;
            std::cout << "SHM Current size is " << runningsize << " / " << size << "\n";
        }

        std::cout << "\n\nDone Inserting\nStarting output\n";

        for(int i = 0; i < numentries; i++){
            certificateStorage tmp = mymap->at(i);
            std::cout << "The key is: " << i << " And the value is: " << tmp.certificate_id << "\n";
        }
    }
    catch(boost::interprocess::interprocess_exception &ex){
        std::cout << "\n shm space wont load wont load\n";
        std::cout << "\n Why: " << ex.what() << "\n";
    }
}

这篇关于ALLOC不好时,抛出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆