相关疑难解决方法(0)

放置new的返回值与其操作数的转换值之间是否存在(语义)差异?

放置new的返回值与其操作数的转换值之间是否存在(语义)差异?

struct Foo { ... };
char buffer[...];

Foo *a = new(buffer) Foo;
Foo *b = reinterpret_cast<Foo *>(buffer);
Run Code Online (Sandbox Code Playgroud)

是否ab以某种方式有什么不同?


编辑:根据DaBler的评论,这个问题告诉我,如果使用const/reference成员则存在差异:使用const成员放置新类和赋值

所以,我的小位的更新问题:是否ab以任何方式不同,如果Foo没有const或引用成员?

c++ strict-aliasing placement-new language-lawyer reinterpret-cast

13
推荐指数
2
解决办法
488
查看次数

是否可以删除未使用新表达式构造的对象?

小心翼翼,这可能不太好.根据cppref:

如果expression是其他任何东西,包括它是否是由new-expression的数组形式获得的指针,则行为是未定义的.

把它放在一边,实际上是下面的代码OK(T非数组,假设new没有替换)?

auto p = (T*)operator new(sizeof(T));
new(p) T{};
delete p;
Run Code Online (Sandbox Code Playgroud)

据说在cppref

当调用分配功能,新的表达通过请求作为第一个参数,类型的字节数 std::size_t,而这正是sizeof(T)对于非数组T.

所以我想这可能还行.但是,据说从C++ 14开始,

允许新表达式忽略或组合通过可替换分配函数进行的分配.在省略的情况下,存储器可以由编译器提供而不需要调用分配函数(这也允许优化掉未使用的new-expression).在组合的情况下,如果满足以下所有条件,则可以扩展由新表达式E1进行的分配以为另一个新表达式E2提供额外的存储:[...]

请注意,只有在使用new-expression时才允许此优化,而不是任何其他方法来调用可替换的分配函数: delete[] new int[10];可以优化,但operator delete(operator new(10));不能.

我不太确定其含义.那么,这在C++ 14中可以吗?

我为什么问这个问题?(来源)

有时,内存分配和初始化无法在一个步骤中完成.您必须手动分配内存,执行其他操作,然后初始化对象,例如,以提供强大的异常安全性.在这种情况下,如果删除表达式无法在结果指针上使用,则必须手动取消初始化和取消分配,这很乏味.更糟糕的是,如果使用新表达式和手动方法,则必须跟踪每个对象使用哪一个.

c++ new-operator dynamic-memory-allocation delete-operator c++14

7
推荐指数
1
解决办法
426
查看次数

当我从 std::vector 中的 new 位置调用析构函数时会发生什么?

如果我有以下

#include <vector>

class C
{
public:
    C()
    :
        m_d(new int)
    {
        *m_d = 2;
    }

    ~C()
    {
        delete m_d;
    }

    int* m_d;
};

int main()
{
    std::vector<char> data;

    data.resize(sizeof(C));

    C* newC = new(&data[0]) C;

    C* cAgain = reinterpret_cast<C*>(&data[0]);
    cAgain->~C();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

究竟会发生什么?当std::vector<char>销毁时,它是否释放了两次内存?如果没有,为什么没有?如果有,你会如何预防?

c++ destructor vector

5
推荐指数
1
解决办法
89
查看次数

自定义分配器,包括放置新案例

我正在尝试为 C++ 实现一个自定义分配器,该分配器适用于任何形式的 new/delete/malloc/free。

我的程序如何工作,我在程序开始时分配 x 字节的内存池并使用它们。例如,当有人编写int* a= new int;我的程序时,将从可用的内存池中返回地址并将其标记为已分配,并且该地址以及分配的大小将从内存池中删除。当有人写入时,delete a;该地址将返回到内存池并可以再次使用。

我的问题是我不完全理解如何new(placement)工作以及应该如何处理它,因为当调用我的函数在 new/malloc 上分配内存时,我只有程序所需的内存大小作为参数,而我只是返回要使用的内存的可用地址。考虑下面的例子

auto p = (std::string*)malloc(5 * sizeof(std::string));
void * placement = p;
new(placement) std::string(4, (char)('a'));
std::cout<< *p;
Run Code Online (Sandbox Code Playgroud)

在第一行,我的自定义分配器将返回 p 来自我的内存池的地址,其中总共有 可用内存5* sizeof(std::string)),在第三行,我的自定义分配器将再次分配返回另一个地址的内存。当我打印时*p,它打印的正是我所期望的aaaa

这是它应该如何运作的吗?

c++ memory-management allocation new-operator

4
推荐指数
1
解决办法
4897
查看次数