0

我目前正在编写一个应用程序,它使用boost::interprocess. 但是我有一些问题boost::interprocess::stringstring从 a中创建 aconst char*就像预期的那样,但是当我尝试创建一个空字符串并稍后用适当的内容填充它时(因为我在创建字符串时不知道它)它以某种方式丢失了第一个字符。以下示例代码说明了这种行为:

#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;
}

此应用程序的输出是SharedMem|haredMem,所以str保持SharedMem,正如预期的那样。但是str2只包含haredMem,缺少字符串的第一个字符。

那么为什么str2缺少一个字符,我该如何避免这种行为呢?

我遇到的另一个问题是,在编译代码时尝试销毁stringsusingdestroy_ptr会导致段错误(这就是我在上面的代码中取消注释倒数第二行时发生的情况)-O3(但似乎只有这样)。这种行为的原因是什么,我需要做些什么来避免段错误?

我在-std=c++0x -O3 -g虚拟机(virtualBox)内的 linux mint 上使用 gcc 4.6.1(编译标志:)和 boost 1.47

编辑: 事实证明,在没有优化的情况下编译时分配工作正常,但在使用-O2or编译时表现出所描述的行为-O3

此外,即使进行优化,分配也有效(至少在这个人为的示例代码中),如果我做两次,使相关代码看起来像这样:

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

虽然到目前为止这似乎避免了这个问题,但它几乎不是我想要依赖的解决方案。

4

1 回答 1

1

压缩评论中的信息

  • 升级编译器。不确定提升,但我认为,编译器有什么问题。无论如何,当使用 g++ 4.8.0(experimental)/4.7.1 和 boost 1.51.0 时,问题不会发生。如果你不能升级你的编译器,那么
  • 设置 -O0、-O1 或 -Os 优化器标志(使用 g++ 4.6.3 和 boost 1.47 进行测试)

另外,我阅读了 g++ man 中关于Optimizer Options. 我尝试将 -Os 禁用的选项与 -O2 标志结合起来,但没有成功。IMO g++ 使用未记录的优化器标志。

于 2012-08-23T17:42:21.290 回答