Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 初始化数组,放置新的,读取变量,定义的行为?_C++_Language Lawyer_Undefined Behavior_Placement New - Fatal编程技术网

C++ 初始化数组,放置新的,读取变量,定义的行为?

C++ 初始化数组,放置新的,读取变量,定义的行为?,c++,language-lawyer,undefined-behavior,placement-new,C++,Language Lawyer,Undefined Behavior,Placement New,给定一个类,它唯一的成员是一个char[10],它既没有继承也没有虚拟成员,它的构造函数没有以任何方式提及数组(这样它就得到了默认初始化->没有初始化,如下所示: class in_place_string { char data[10]; static struct pre_initialized_type {} pre_initialized; in_place_string(pre_initialized_type) {} //This is the const

给定一个类,它唯一的成员是一个
char[10]
,它既没有继承也没有虚拟成员,它的构造函数没有以任何方式提及数组(这样它就得到了默认初始化->没有初始化,如下所示:

class in_place_string {
    char data[10];

    static struct pre_initialized_type {} pre_initialized;
    in_place_string(pre_initialized_type) {}  //This is the constructor in question

    in_place_string() :data() {} //this is so you don't yell at me, not relevent
};
是否定义了将新类放置到已经有数据的缓冲区中,然后从数组成员读取的行为

int main() {
    char buffer[sizeof(in_place_string)] = "HI!";
    in_place_string* str = new(buffer) in_place_string(in_place_string::pre_initialized);
    cout << str->data; //undefined behavior?
}
intmain(){
字符缓冲区[sizeof(in_place_string)]=“嗨!”;
in_place_string*str=new(buffer)in_place_string(in_place_string::pre_initialized);
cout data;//未定义的行为?
}

我很确定它没有很好的定义,所以我想问这是实现定义的还是未定义的行为。

我认为相关条款是8.5[dcl.init]第12段:

如果未为对象指定初始值设定项,则该对象默认已初始化。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,如果未对该对象执行初始化,则该对象保留不确定值,直到替换该值为止(5.17)。[注:具有静态或线程存储持续时间的对象初始化为零,请参见3.6.2.-结束注]如果通过评估产生不确定值,则行为未定义,除非在 以下情况:

  • 如果通过计算以下各项产生无符号窄字符类型(3.9.1)的不确定值:
    • 条件表达式(5.16)的第二个或第三个操作数
    • 逗号表达式(5.18)的右操作数
    • 转换为无符号窄字符类型(4.7、5.2.3、5.2.9、5.4)或
    • 一个废弃的值表达式(第5条),则运算的结果是一个不确定的值
  • 如果通过计算简单赋值运算符(5.17)的右操作数(其第一个操作数是无符号窄字符类型的左值)生成无符号窄字符类型的不确定值,则不确定值将替换左操作数引用的对象的值
  • 如果初始化无符号窄字符类型的对象时,通过计算初始化表达式生成了无符号窄字符类型的不确定值,则该对象将初始化为不确定值

我认为任何异常都不适用。由于在构造对象后初始化之前读取了值,我认为代码会导致未定义的行为。

您没有执行
重新解释\u cast
(这是不安全的,因为类具有非平凡的初始化);您正在创建其成员未初始化的新对象

对未初始化的对象执行左值->右值转换会给出一个不确定的值和未定义的行为。对象是否未初始化

根据5.3.4,由新表达式创建的所有对象都具有动态存储持续时间。新放置也不例外

由新表达式创建的实体具有动态存储持续时间

然后8.5表示

如果没有为对象指定初始值设定项,则默认初始化该对象。当获得具有自动或动态存储持续时间的对象存储时,该对象具有不确定值,如果未对该对象执行初始化,则该对象将保留不确定值,直到该值替换lue(5.17)。[注:具有静态或线程存储持续时间的对象初始化为零,请参见结束注释]如果通过评估生成不确定值,则行为未定义,但以下情况除外:

以下情况只允许
无符号字符
,即使这样,该值也没有用处


在您的情况下,新对象具有动态存储持续时间(!)没有进行初始化的成员具有不确定的值。读取它们会产生不确定的行为。

@DietmarKühl怎么没有保证?它是类的第一个成员,在缓冲区的开头构造位置。
数据
还能在哪里?@DietmarKühl:我不喜欢考虑corre在所有人中,我敢肯定,在地址处放置新构件的定义是明确的。根据5.3.4[expr.new]第11段,似乎没有太大的回旋余地:“…该参数不得小于正在创建的对象的大小;只有当对象是数组时,该参数才可以大于正在创建的对象的大小…”。。。"由于大小与对象侧匹配,因此对象需要精确地位于指定区域。我仍然非常确定代码未定义…@Barry:这是一个标准布局类,这是非常相关的,否则第一个成员可能不在开始处。与引人入胜相关的是,我认为所有
无符号字符
异常也是一个例外应用于
char
。我想知道将缓冲区转换为
无符号char
是否可以解决问题,但4.1/2有点难thick@MooingDuck:否,
unsigned char
的异常只会使不确定值传播而不会导致UB。该值仍然不可用。我觉得奇怪的是,新的位置会导致初始化已初始化的数组将变为“未初始化”@MooingDuck:它创建了一个全新的对象。您的“已初始化数组”没有变为未初始化,它已不存在(其存储已被重用)。