placement new

2 阅读2分钟

placement new 是 C++ 中的一个特性,用于在已分配的内存上构造对象,而不是在自由存储区(heap)上分配内存并构造对象。它的语法形式如下:

new (pointer) Type (arguments);

其中,pointer 是已分配内存的地址,Type 是要构造的对象类型,arguments 是传递给对象构造函数的参数。

通过 placement new,可以在特定的内存位置上创建对象,这在某些情况下非常有用,比如在共享内存、内存池等场景中。由于 placement new 可以显式地指定对象的构造位置,因此它提供了更多的灵活性和控制权。

需要注意的是,使用 placement new 构造的对象,在使用完毕后需要手动调用其析构函数来释放资源,并通过调用 delete 或者 delete[] 来释放其占用的内存。

例子:

  1. void *shmaddr = mmap(NULL, size_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

    • mmap函数用于将一个文件或者其他对象映射到内存中。NULL表示内核选择映射的地址,size_表示映射的大小,PROT_READ | PROT_WRITE表示允许读写访问,MAP_SHARED表示映射的内存区域可被多个进程共享,fd是打开的文件描述符,0表示从文件的起始位置开始映射。
  2. new(shmaddr) ShmSlice(init);

    • 在映射的共享内存地址上使用placement new语法构造一个ShmSlice对象,init是构造函数的参数。
  3. auto deleter = [](ShmSlice *ptr) { ptr->~ShmSlice(); }

    • 创建一个lambda表达式作为deleter,用于在std::shared_ptr销毁时调用ShmSlice对象的析构函数。
  4. slice_ = std::shared_ptr<ShmSlice>(reinterpret_cast<ShmSlice *>(shmaddr), deleter);

    • 创建一个std::shared_ptr对象slice_,将其与映射的共享内存地址关联,并指定了上述自定义的deleter函数。reinterpret_cast用于将void*指针转换为ShmSlice*指针。

这样,通过std::shared_ptr的管理,确保了在共享内存不再被引用时,对象会被正确地销毁,从而释放共享内存。