Search code examples
c++boost-interprocess

boost::interprocess::string missing a character and segfaulting on destruction


I'm currently writing an application, which communicates with another application using boost::interprocess. However I have some problems with boost::interprocess::string. Creating a string from a const char* works just as expected, however when I try to create an empty string and later fill it with appropriate content (since I don't know it when creating the string) it somehow looses the first character. The following example code illustrates this behaviour:

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

namespace ip = boost::interprocess;
int main(int ac, char* av[]){
    typedef ip::allocator<char,ip::managed_shared_memory::segment_manager>   IpStringAllocator;
    typedef ip::basic_string<char, std::char_traits<char>,IpStringAllocator> IpString;
    const char* name = "SharedMem";
    ip::shared_memory_object::remove(name);

    ip::managed_shared_memory mem(ip::create_only ,name ,65536);
    auto str  = mem.construct<IpString>("string")(name, mem.get_segment_manager());
    auto str2 = mem.construct<IpString>("string2")("", mem.get_segment_manager());
    *str2     = name;
    std::cout<<*str<<"|"<<*str2<<std::endl;
    //mem.destroy_ptr<IpString>(str);
    //mem.destroy_ptr<IpString>(str2);
    return 0;
}

The output of this application is SharedMem|haredMem, so str holds SharedMem, just as expected. However str2 only contains haredMem, missing the first character of the string.

So why is str2 missing one character and how do I avoid this behaviour?

Another problem I'm having is that trying to destroy the strings using destroy_ptr leads to a segfault (that is what happens when I uncomment the two second to last lines in the code above) when compiling the code with -O3 (but only then it seems). What is the reason for that behaviour and what do I need to do differently to avoid the segfault?

I'm using gcc 4.6.1 (compile flags: -std=c++0x -O3 -g) and boost 1.47 on linux mint inside a virtual machine (virtualBox)

Edit: As it turns out the assignment works fine when compiling without optimizations, but exhibits the described behaviour when compiling with -O2 or -O3.

Furthermore the assignment works (at least in this contrieved sample code) even with optimization, if I do it twice, making the relevant code look like this:

auto str2 = mem.construct<IpString>("string2")("", mem.get_segment_manager());
*str2     = name;
*str2     = name;
std::cout<<*str<<"|"<<*str2<<std::endl;

While this seems to avoid the problem so far it is hardly a solution I would want to depend on.


Solution

  • Compress information from comments

    • Upgrade compiler. No sure about boost, but I think, what problem in compiler. Anyway, when using g++ 4.8.0(experimental)/4.7.1 and boost 1.51.0 the problem does not occur. If you can't upgrade your compiler, then
    • Set -O0, -O1 or -Os optimizer flag(testing with g++ 4.6.3 and boost 1.47)

    Also, I read section in g++ man about Optimizer Options. I tried to combine options that disabled by -Os with -O2 flag, but I was not successful. IMO g++ use undocumented optimizer flags.