安置新的和例外

5 c++ exception-handling placement-new c++11 nothrow

“placement new”运算符声明如下:

void* operator new (std::size_t size, void* ptr) noexcept;
Run Code Online (Sandbox Code Playgroud)

但是虽然它不涉及任何实际分配,因此消除了错误的分配异常,但指针仍然可能指向错误的位置,在这种情况下,人们会期望得到范围或上溢/下溢错误,但不会它被声明为noexcept简单地终止执行的事实?

这是否也意味着在 C++11 放置之前 new 将抛出并尝试处理一个std::unexpectedstd::set_unexpected而不是直接崩溃?

不应该有大量的放置新“以防万一”吗?

rav*_*avi 5

使用放置语法的目的是实现非标准分配,因此通常需要非标准释放。因此,采取的行动取决于所使用的分配器。

您的工作是为新工作的安置提供正确的地址。

针对评论进行编辑:-

#include <new>        // Must #include this to use "placement new"
#include "Fred.h"     // Declaration of class Fred

    void someCode()
    {
      char memory[sizeof(Fred)];     // Line #1     //Allocate enough memory.
      void* place = memory;          // Line #2     // There's no need for this.

      Fred* f = new(place) Fred();   // Line #3 (see "NOTE" below)
      // The pointers f and place will be equal

      ...
    }
Run Code Online (Sandbox Code Playgroud)

注意:您对传递给“placement new”操作符的指针指向一个足够大的内存区域并为您创建的对象类型正确对齐负全责。编译器和运行时系统都不会尝试检查您是否正确执行此操作。如果您的 Fred 类需要在 4 字节边界上对齐,但您提供的位置没有正确对齐,那么您可能会遇到严重的灾难。

简而言之,这意味着你应该小心使用放置 new 或者如果你像我这样的人永远不要使用它:)

希望这能消除您的疑虑。


def*_*ube 0

放置的new存在是为了使显式构造函数调用能够定位到任意缓冲区(用于自定义分配器、调试等)。就是这样。

您可以编写自己的代码来验证其输入。

例如:一个类可能需要某种对齐方式,并且您怀疑某些自定义分配器捏造了这一点。因此,您给该类一个不同的新位置,然后看看当所述分配器使用它时会发生什么。