Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.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++ 在放置新数据之前初始化数据是未定义的行为吗? struct A{//POD类 字符数据[10]; void print(){std::cout print();//从内存缓冲区读取 a->~a(); }_C++_Language Lawyer_Undefined Behavior_Object Lifetime_Placement New - Fatal编程技术网

C++ 在放置新数据之前初始化数据是未定义的行为吗? struct A{//POD类 字符数据[10]; void print(){std::cout print();//从内存缓冲区读取 a->~a(); }

C++ 在放置新数据之前初始化数据是未定义的行为吗? struct A{//POD类 字符数据[10]; void print(){std::cout print();//从内存缓冲区读取 a->~a(); },c++,language-lawyer,undefined-behavior,object-lifetime,placement-new,C++,Language Lawyer,Undefined Behavior,Object Lifetime,Placement New,从类的角度来看,这是从未初始化的内存中读取,但从内存的角度来看,内存实际上是初始化的。这是未定义的行为,还是仅仅是危险的行为 [注意:对于那些好奇的人来说,这称为“placement new”,用于在内存中的特定缓冲区中构造对象。这是wasvector在其内部缓冲区中构造类所做的工作]即使在这种特殊情况下保证类成员和数组具有相同的地址(再加上编译器除了将对象放在缓冲区的开头之外,实际上不允许编译器做任何事情),我很确定这是一种未定义的行为 我相信该标准的相关部分是: 当获得具有自动或动态存储持续

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


[注意:对于那些好奇的人来说,这称为“placement new”,用于在内存中的特定缓冲区中构造对象。这是was
vector
在其内部缓冲区中构造类所做的工作]

即使在这种特殊情况下保证类成员和数组具有相同的地址(再加上编译器除了将对象放在缓冲区的开头之外,实际上不允许编译器做任何事情),我很确定这是一种未定义的行为

我相信该标准的相关部分是:

当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,如果未对该对象执行初始化,则该对象将保留不确定值,直到替换该值([expr.ass])


我不知道标准中有任何额外的措辞,在任何情况下都会根据对象在其生命周期开始之前创建的存储中的内容来保证对象的初始值。您的对象是默认初始化的,属于类类型,因此,将调用默认构造函数。没有构造函数中的成员的em初始值设定项,或者类中没有默认初始值设定项,因此,该成员将被默认初始化。由于数组的元素是基本类型,。这意味着这适用于数组内容的任何使用(这将发生在
操作符内部,即使在这种特殊情况下保证类成员和数组具有相同的地址(加上事实是,除了将对象放在缓冲区的开头,编译器实际上不允许执行任何操作),我很确定这是未定义的行为

我相信该标准的相关部分是:

当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,如果未对该对象执行初始化,则该对象将保留不确定值,直到替换该值([expr.ass])


我不知道标准中有任何额外的措辞,在任何情况下都会根据对象在其生命周期开始之前创建的存储中的内容来保证对象的初始值。您的对象是默认初始化的,属于类类型,因此,将调用默认构造函数。没有构造函数中的成员的em初始值设定项,或者类中没有默认初始值设定项,因此,该成员将被默认初始化。由于数组的元素是基本类型,。这意味着这适用于数组内容的任何使用(这将发生在
操作符内部构建对象后缓冲区的状态是未定义的。编译器可以在构建
A
期间自由地将
格式c;:“
写入其中。他们还可以自由地优化缓冲区的预加载,只需丢弃您在该行所做的操作即可


然后,您的
打印
代码将作为
对象构造后缓冲区的状态是未定义的。编译器可以在
A
的构造过程中自由地将
格式c;:“
写入其中。他们还可以自由地优化缓冲区的预加载,只需丢弃您在该行所做的操作即可


您的
打印
代码随后将被转换为
,尽管编译器将新位置解释为“导入”通常不需要任何成本在构建对象之前,无论存储中碰巧存在什么位模式,都有一些难以描述的情况,这样做可能会大大复杂化或阻碍优化,而不会带来任何实际好处。因此,该标准允许编译器在不需要任何成本或不需要任何成本的情况下导入位模式使客户受益,而不要求他们这样做,因为这样做会很昂贵,而不会使客户受益

虽然如果有一种新的语法形式可以明确指定应该导入位模式,这会很有帮助,但在编写标准时,这样的事情并不被认为是必要的。在大多数情况下,导入位模式是有用的,它不会花费任何成本,编译器也会这样做,无论是否强制。在在没有用的情况下,编译器是否支持该行为无关紧要。这种语法会导致编译器做一些有用的事情,而这些事情本来是不会做的,这种情况非常罕见,因此没有必要容纳它们


显然,自placement new首次标准化以来的几十年中,编译器的理念已经发生了变化,按位导入很有用,但编译器无法可靠地支持它的情况更为常见。明智的解决方案是添加两种新的语法形式——一种是要求编译器导入位模式ern和另一个明确声明位模式不重要的代码,其基础是程序员可能比编译器编写人员更了解位模式是否重要。然而,到目前为止,这种情况还没有发生,这使得像您这样的结构处于尴尬的状态,无法得到一些简单代码的有效支持没有任何好的方法来识别支持它们的实现。

尽管编译器通常不需要任何成本
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();
}