c++ - boost::interprocess::string 缺少一个字符并在销毁时出现段错误

标签 c++ boost-interprocess

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

#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 缺少一个字符,我该如何避免这种行为?

我遇到的另一个问题是,尝试使用 destroy_ptr 破坏 strings 会导致段错误(当我取消对倒数第二行的注释时会发生这种情况在上面的代码中)用 -O3 编译代码时(但似乎只有那时)。这种行为的原因是什么?我需要采取哪些不同的措施来避免段错误?

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

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

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

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

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

最佳答案

压缩评论中的信息

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

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

关于c++ - boost::interprocess::string 缺少一个字符并在销毁时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12038247/

相关文章:

c++ - void* 指向指针

c++ - b2 的命令参数,以便使用 Microsoft 的 Clang/C2 构建 Boost 库

mysql - mysql中同步存储过程执行

c++ - C++链表声明中的语法错误

c# - 从子文件夹链接 dll

c++ - 在 C++ 中二进制搜索具有给定元素值的元组

c++ - 基于文件的查找表

c++ - 为什么 boost interprocess named mutex docs 说每个进程都应该有自己的命名互斥体?

c++ - 将文件中的非连续 block 映射到连续的内存地址

c++ - boost::32 和 64 位进程之间的进程间共享内存