c++ - 在放置新数据之前初始化数据是未定义的行为吗?

标签 c++ language-lawyer undefined-behavior object-lifetime placement-new

struct A { //POD class
    char data[10];
    void print() {std::cout << data;}
};
int main() {
    char buffer[11] = "HELLO"; //sets values in buffer
    A* a = new(buffer)A;
    a->print(); // read from memory buffer
    a->~A();
}

从类的角度来看,这是对未初始化内存的读取,但从内存的角度来看,内存实际上已被初始化。这是未定义的行为,还是仅仅是危险的?

[注意:对于那些对new(buffer)A and a->~A()感兴趣的人,这称为“放置新”,用于在内存中的特定缓冲区中构造对象。这是 vector 在其内部缓冲区中构造类的幕后工作]

最佳答案

即使类成员和数组在这种特殊情况下保证具有相同的地址(基于 [basic.compound]/4.3 加上 requirements on new-expressions 实际上不允许编译器做任何其他事情,而不是把它对象就在缓冲区的开头),我很确定这是未定义的行为。

我相信标准的相关部分是 basic.memobj §1 :

When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]).

我不知道标准中有任何额外的措辞在任何情况下都会根据对象在其生命周期开始之前创建的存储中的内容来保证对象的初始值。您的对象是默认初始化的并且是类类型的,因此将调用默认构造函数。构造函数中的成员没有 mem-initializer,类中也没有默认初始化程序,因此,成员将被默认初始化 [class.base.init/9.3] .由于数组的元素是基本类型,no initialization will be performed for them .这意味着 basic.indet §2适用于对数组内容的任何使用(这将发生在 operator << 中)

If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases […]

由于您的案例不匹配任何列为异常的案例,您的程序应该有未定义的行为......

关于c++ - 在放置新数据之前初始化数据是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53748543/

相关文章:

c++ - C++中调用成员函数是否需要使用->运算符?

全局变量/全局命名空间的 JavaScript 策略

c - 整数常量指向的对象的默认类型

c - 如果一个变量未初始化,它什么时候抛出错误,什么时候给出垃圾值?

c++ - 如何处理 LLVM metadata.h 的变化

c++ - 标识符 "__builtin_expect"未定义(在 win 教程-谈话者示例中的 ROS 期间)

C++ 类型和函数

c++ - 允许编译器优化堆内存分配吗?

java - JColorChooser 中的异常行为(或可能的错误)

c - malloced 内存未定义写前读?