3

I'm using boost shared memory to share data between 32bit and 64bit processes.

Under 64bit everything works fine, but under 32bit I get a compilation error whenever I need to allocate new elements to a vector<string>. string alone works without problems, also no problems with vector<uint32_t>. It's really only the vector<string> that seems to be at odds:

error C2718: 'boost::container::basic_string,MDSDATA::char_allocator>': actual parameter with requested alignment of 8 won't be aligned

The shared memory is defined with alignment of uint64_t for 32bit-64bit compatibility:

namespace bipc = boost::interprocess;
namespace bc = boost::container;
typedef bipc::basic_managed_windows_shared_memory
     <  char
     ,  bipc::rbtree_best_fit
        <
            bipc::mutex_family,
            bipc::offset_ptr<void, int32_t, uint64_t>
        >
     ,  bipc::iset_index
     >                                                          managed_shm_type;

typedef bc::scoped_allocator_adaptor<bipc::allocator<void, segment_manager_t> > void_allocator;
typedef void_allocator::rebind<char>::other                     char_allocator;
typedef bc::basic_string
        <
            char,
            std::char_traits<char>,
            char_allocator
        >                                                       char_string;
typedef void_allocator::rebind<char_string>::other              string_allocator;
typedef bc::vector<char_string, string_allocator>               string_vector;

I only get the compilation error whenever I add code that reallocates elements in the vector like emplace_back(), resize(), insert() etc. Like in the following piece of code:

string_vector & list(segment->getListvectorReference());
list.clear();                 // this works fine
list.emplace_back("hello");   // this fails
list.resize(20);              // this fails too

An important note is the following: If I remove the code that causes the compilation error in the 32bit build, I am able to create new elements of the vector from the 64bit side and read them correctly from 32bit. It's just the opposite direction (32bit allocating the strings) that doesn't work.


Update:

Following this post and the respective patch, I came to the assumption that this might be an issue with the Microsoft Compiler in conjunction with boost. I'm using Visual Studio 2015 Express Update 3. This is also supported by the error message itself that points to the file boost/move/detail/type_traits.hpp. I have the gut-feel that there may be an easy patch available to fix this in boost.

Unfortunately, my knowledge is not sufficient to come up with a patch that would fix this issue in boost. However, I'll give credit to anybody that is able to provide a solution.

For the time being I can live with this bug since I realized that my software will never allocate these strings from the 32bit code.


Update 2: There was a fix applied in boost 1.64 that has some relation to this issue.

user23573
  • 2,479
  • 1
  • 17
  • 36
  • Try: `typedef __declspec(align(8)) void_allocator::rebind::other string_allocator;` – Rotem Jul 19 '16 at 18:33
  • @Rotem, unfortunately this does not work. I've tried it with both, the `string_allocator` and the `char_allocator` as well as with the `vector_string`. All variants produce the same error still while compiling fine on 64bit. – user23573 Jul 20 '16 at 06:58
  • Right, according to Microsoft documentation [link](https://msdn.microsoft.com/en-us/library/sxe76d9e.aspx), you should actually avoid using `__declspec(align())` for `typedef`s – Rotem Jul 20 '16 at 20:35
  • Are you using declaration like: `typedef struct __declspec(align(32)) AlignedStruct`, or is it deep inside BOOST implementation? – Rotem Jul 20 '16 at 20:38
  • No, all of these `__declspec(align(xx))` stuff is inside boost. (If there is...) In my code, I have not a single `__declspec` declaration since I'm trying to be as crossplatform capable as possible. – user23573 Jul 20 '16 at 21:27

0 Answers0