首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >放置新的和异常

放置新的和异常
EN

Stack Overflow用户
提问于 2014-11-02 20:32:33
回答 4查看 2.3K关注 0票数 5

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

代码语言:javascript
运行
复制
void* operator new (std::size_t size, void* ptr) noexcept;

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

这是否意味着在放置C++11之前,new将抛出并尝试在std::set_unexpected情况下处理std::unexpected,而不是直接崩溃?

难道不应该有一个重载的位置新的“以防万一”?

EN

回答 4

Stack Overflow用户

发布于 2014-11-02 20:58:46

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

你的工作就是为新员工提供正确的工作地址。

为回应评论而编辑:

代码语言:javascript
运行
复制
#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

      ...
    }

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

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

希望这能消除你的疑虑。

票数 5
EN

Stack Overflow用户

发布于 2014-11-02 21:42:12

要理解这个函数的作用,我认为有必要看一看new-expression的作用:它调用一个分配函数来获取对象的存储空间,然后在分配函数指定的内存区域中构造该对象(通过返回指向所述内存区域的指针)。

这意味着构造永远不会由分配函数本身执行。分配函数有一个奇怪的名字operator new

可以通过使用placement-new语法为分配函数提供其他参数:

代码语言:javascript
运行
复制
new int(5)        // non-placement form
new(1,2,3) int(5) // placement-form

但是,placement new通常引用一个非常具体的new-expression

代码语言:javascript
运行
复制
void* address = ...;
::new(address) int(5) // "the" placement-form

这种形式的目的是在已经分配的内存区域中构造一个对象,即它只调用构造函数,而不执行任何分配。

在核心语言中还没有为这种情况引入特殊情况。相反,在标准库中添加了一个特殊的分配函数:

代码语言:javascript
运行
复制
void* operator new (std::size_t size, void* ptr) noexcept;

作为一个无操作(return ptr;),它允许显式地调用对象的构造函数,在给定的内存位置进行构造。编译器可以消除这种函数调用,因此不会引入任何开销。

票数 3
EN

Stack Overflow用户

发布于 2014-11-02 20:49:21

Placement new的存在使得显式构造函数调用可以指向任意缓冲区(用于自定义分配器、调试等)。事情就是这样。

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

例如:一个类可能需要某种对齐,而您怀疑某个自定义分配器在编造这一点。所以,你给这个类一个不同的位置,看看当分配器使用它时会发生什么。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26699326

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档