0

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.

Grizzly
  • 19,595
  • 4
  • 60
  • 78
  • Please, specify your compiler and boost's version. I have g++ 4.8.0 and boost 1.50. All ok, SharedMem|SharedMem and without segfault – awesoon Aug 20 '12 at 13:23
  • @soon: I'm using gcc 4.6.1 and boost 1.47. Added that info to the question – Grizzly Aug 20 '12 at 13:31
  • can you upgrade your compiler? I tried to reproduce your problem, but there was only g++ 4.6.3 in repository. Output: SharedMem|SharedMem. I can make a old version of g++, but it will take some time. – awesoon Aug 20 '12 at 15:11
  • @soon: I tried it with g++ 4.6.3 now. Output remains the same, although it does not produce segfaults when destroying the strings. Upgrading the compiler is theoretically possible, but I would rather avoid it, since I'm not the only one working on the project, making such changes a nontrivial endeavour – Grizzly Aug 20 '12 at 18:43
  • Do you use the optimization flags? Now, I tried to compile with -O3/-O2 - the output is haredMem, but with -O1/-O0 the output is SharedMem. – awesoon Aug 23 '12 at 14:59
  • @soon: I was indeed compiling with `-O3`, completely forgot about that. Doing the test without optimization leads to the correct output (of course this is hardly a desiarable result). I have added that info to the question. Since you already tried it with newer versions of boost/gcc: does the behaviour persists for those? – Grizzly Aug 23 '12 at 15:21
  • g++ 4.8.0/4.7.1, boost 1.51.0: compilation with any optimizer flags leads to correct output. – awesoon Aug 23 '12 at 15:39
  • @soon: Seems like I'll have to press for updating boost and possibly g++. Thanks for the info. Want to compress those informations into an answer so I can accept that? – Grizzly Aug 23 '12 at 16:43

1 Answers1

1

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.

awesoon
  • 32,469
  • 11
  • 74
  • 99