Bad address is dropping

I get "bad_alloc" while trying to work with extended managed shared memory. I copied the enhancement example from my quick guide for the impatient and included my own changes. My code is below, I commented on the sample material and wrote it below. I also added some debugging and testing materials.

Does anyone have any ideas? Any help is much 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> 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 exit ...

  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 
+3
source share
1 answer

It seems you just don't have enough memory. You can assume that you should not, as individual distributions do not occupy the volume of space.

But memory fragmentation can do this: if there is sufficient โ€œpaddingโ€ or โ€œoverheadโ€ in shared memory objects, you can exit the contiguous space.

Either save the data in a pre-selected vector (for example,), or use one of the more intelligent distribution algorithms between processes:

The simplest way to resolve it in this case, apparently, will simply make the shared memory area twice as large (the minimum size is a 4K memory page on most systems).

I just used 2*size and the tests completed.

Update / Corrections

I just checked that something really does the "vector way" much more efficiently: replacing std::map with boost flat_map gives you vector storage.

The big difference is that each node on the map is dynamically allocated, which leads to a fixed invoice linearly consuming available memory.

enter image description here

Observations

  • There was significant upfront overhead, consuming 320 bytes before anything happened.
  • with flat_map , you also keep the vector capacity up, you see that you can only win a small extra storage efficiency.

The above chart was created at the output of the next program. Look for the get_free_memory() calls. To switch the map implementation, just change #if 0 to #if 1 . (Notice how I cleared some of the code that was useless for reuse and used exceptions to control the flow).

 #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"; } } 
+8
source

Source: https://habr.com/ru/post/1204448/


All Articles