当前位置: 首页 > 知识库问答 >
问题:

在SharedMemory中已存在的对象上放置新对象

齐文栋
2023-03-14

我有两个程序。第一个分配共享内存文件,第二个从中读取。。我使用placement new将对象放置到此内存中,以确保对象不会使用新的或分配共享内存文件之外的任何内存。

我的阵列结构:

template<typename T, size_t Size>
struct SHMArray {
    SHMArray() : ptr(elements) {}
    SHMArray(const SHMArray& other) { std::copy(other.begin(), other.end(), begin()); }

    SHMArray(SHMArray&& other)
    {
        std::swap(other.ptr, ptr);
        std::fill_n(ptr.get(), Size, T());
    }

    ~SHMArray()
    {
        std::fill_n(ptr.get(), Size, T());
    }

    constexpr bool empty() const noexcept
    {
        return Size == 0;
    }

    constexpr size_type size() const noexcept
    {
        return Size;
    }

    T& operator[](std::size_t pos)
    {
        return *(ptr.get() + pos);
    }

    constexpr const T& operator[](std::size_t pos) const
    {
        return *(ptr.get() + pos);
    }

    T* data() noexcept
    {
        return ptr.get();
    }

    constexpr const T* data() const noexcept
    {
        return ptr.get();
    }

private:
    offset_ptr<T> ptr;
    T elements[];
};

方案1:

int main()
{
    //Allocate a shared memory file of 1mb..
    auto memory_map = SharedMemoryFile("./memory.map", 1024 * 1024, std::ios::in | std::ios::out);

   memory_map.lock();

   //Pointer to the shared memory.
   void* data = memory_map.data();

   //Place the object in the memory..
   SHMArray<int, 3>* array = ::new(data) SHMArray<int, 3>();
   (*array)[0] = 500;
   (*array)[1] = 300;
   (*array)[2] = 200;

   memory_map.unlock(); //signals other program it's okay to read..
}

方案2:

int main()
{
    //Open the file..
    auto memory_map = SharedMemoryFile("./memory.map", 1024 * 1024, std::ios::in | std::ios::out);

   memory_map.lock();

   //Pointer to the shared memory.
   void* data = memory_map.data();

   //Place the object in the memory..
   //I already understand that I could just cast the `data` to an SHMArray..
   SHMArray<int, 3>* array = ::new(data) SHMArray<int, 3>();
   for (int i = 0; i < array.size(); ++i)
   {
       std::cout<<(*array)[i]<<"\n";
   }

   memory_map.unlock(); //signals other program it's okay to read..
}

>

  • 程序一将SHMArray放置在内存中,位置为new。程序二在程序一已经放置的对象上做同样的事情(覆盖它)。这是未定义的行为吗?我认为不是,但我想确认一下。

    两个程序都不调用析构函数数组-

    我基本上是在假设placement new正在工作,就像我在这个特定场景中通过:struct-SHMArray*数组=(struct-SHMArray*)数据在内存中放置了一个C结构一样 。。这是正确的吗?


  • 共有1个答案

    谷梁俊楚
    2023-03-14

    我基本上是假设placement new正在工作,就像我在这个特定场景中通过:struct SHMArray*数组=(struct SHMArray*)data;将C结构放入内存一样;。。这是正确的吗?

    不,这是不对的。Placement new还调用对象的适当构造函数。“struct-SHMArray*数组=(struct-SHMArray*)数据;”不会调用任何对象的构造函数。这只是一个指针转换转换。它不会调用任何人的构造函数。关键区别。

    在示例代码中,您确实希望调用模板化对象的构造函数。尽管所示示例还有其他问题,如评论中所述,但这似乎是在这种特定情况下需要做的事情。

    但是就相当于放置new和指针强制转换而言,不,它们是不一样的。一个调用构造函数,一个不调用。new总是调用构造函数,不管它是不是放置new。这是一个非常重要的细节,不容忽视。

     类似资料: