【问题标题】:C++, Is it safe to static_cast to void* and back across processes?C++,static_cast 到 void* 并跨进程返回是否安全?
【发布时间】:2018-01-31 02:52:12
【问题描述】:

我有两个相同的二进制文件在 Linux 系统上同时运行(不同的命令行参数,所以它们做不同的事情)。在一个进程中,我将一个对象 memcopy 到某个共享内存区域;在另一个过程中,我检索具有正确大小的对象,并以void* 的形式获取指向它的指针,并将static_cast 指向原始类型的指针。

这被认为是安全的吗?对象不一定是 POD。

【问题讨论】:

  • 你永远不应该使用void*
  • @JakeFreeman 这有点夸张,在处理原始内存时 void* 很常见。 mallocmemcpy
  • 实际上,是的,只要类没有指向内部数据成员、引用或虚拟的指针,Folly 就会实现这一点。在纯理论中,没有。 Folly、Bloimberg 和 EASTL 都有自己的类型重定位版本,以避免移动构造函数,这些构造函数基本上都在一定程度上涉及非平凡类型的 memcpy。
  • @NirFriedman 通常用于 C++,您永远不需要直接使用 void*
  • 使用void* 通常是不可避免的,因为低级(OS)API。但是,在 C++ 中,您会将这些接口包装在类型安全的 C++ 接口中。这会将void* 的使用本地化到一个地方(通常是一个类),因此您的大部分应用程序不会受到影响。

标签: c++ ipc type-safety static-cast memory-safety


【解决方案1】:

这是不安全的,因为你不能 memcpy 一个不是 trivially_copyable 的对象。例如,您不能通过调用 memcopy 来移动/复制 std::vector,这可能会导致很多问题。但是,您可以将对象构造到共享内存段中。我强烈建议查看 boost 进程间;即使您不使用它,这些示例也会让您了解什么是可能的:http://www.boost.org/doc/libs/1_63_0/doc/html/interprocess/sharedmemorybetweenprocesses.html

【讨论】:

  • 公平地说,你的计算机因为大多数重要的内存数据而崩溃的可能性非常低,除非该类型是虚拟的、包含引用或指向内部变量的指针。像 Folly 这样的主要图书馆广泛使用它。 github.com/facebook/folly/blob/master/folly/docs/…
  • @AlexanderHuszagh: memcpy-ing std::vector<T> 到共享内存肯定会在其他进程中爆炸,即使它不包含指向内部变量的指针。问题是您的memcpy 将复制向量对象本身,这通常只是一堆指向堆分配内存的T*
【解决方案2】:

语言没有提到共享内存,所以从这个意义上说,这个问题是无法回答的。在实践中,对琐碎可复制的限制是正确的想法。由于允许通过memcpy 为此类对象赋值,因此编译器通常不会进行任何不幸的优化。

您必须注意在不同进程中在不同地址加载的内存。如果对象包含没有指针,这可以被忽略。如果是这样,您可能需要offset_ptr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-04
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2014-05-30
    • 2011-12-10
    相关资源
    最近更新 更多