【问题标题】:Can std::malloc create an object? Is placement new always required? [duplicate]std::malloc 可以创建对象吗?是否总是需要安置新的? [复制]
【发布时间】:2018-02-07 19:41:13
【问题描述】:

这段代码在 C++ 中是否有未定义的行为?

#include <cstdlib>

int main() {
    int *ip = static_cast<int *>(std::malloc(sizeof *ip));
    *ip = 42; //is this accessing an object that has not started its lifetime?
    free(ip);
}

注意事项:
std::malloc has the semantics that it has in C。在 C 中std::malloc 创建了有效的ints,所以它应该是有效的?

对象或引用的生命周期是 对象或参考。据说一个物体是非真空的 初始化,如果它是类或聚合类型,并且它或其中之一 它的子对象由构造函数初始化,而不是平凡的 默认构造函数。 [ 注意:通过简单的复制/移动初始化 构造函数是非空初始化。 —— 尾注 ] 一生 类型 T 的对象在以下时间开始:

(1.1) 获得了类型 T 具有正确对齐和大小的存储,并且
(1.2) 如果对象有非空初始化,则其初始化完成,

除非对象是联合成员或其子对象...

source

我很确定这句话回答了我的问题,但我不太明白它是说是还是不是。

【问题讨论】:

  • 那句话是不相关的,这已经被讨论过 100 万次了。等一下,我去找个骗子。
  • 不要在 C++ 中使用 malloc/free。使用new/delete。或者更好;别。使用 RAII、自动对象、容器和智能指针,避免手动内存管理。
  • 我认为标准委员会将“非平凡初始化”更改为“非空初始化”是有充分理由的,但我肯定不喜欢这个新术语。我认为那个链接上的“空洞”可能来自一些基于计算机的语言翻译或其他东西,但我看到它是在 C++17 中。

标签: c++ language-lawyer


【解决方案1】:

您的对象具有int 类型,它不需要重要的初始化,因此只需调用std::malloc 即可满足两个要点。

如果对象需要一个重要的构造函数调用,那么 new 是满足 (1.2) 的方法,如果您想使用除 operator new() 之外的分配器,那么放置 new 是正确的方法。

【讨论】:

    猜你喜欢
    • 2020-08-26
    • 2015-05-22
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多