C++ 新工作是如何进行的?

C++ 新工作是如何进行的?,c++,memory,segmentation-fault,placement-new,C++,Memory,Segmentation Fault,Placement New,我写了以下内容,认为它应该在运行时出错。 然而它不是,它运行良好,我不明白为什么 #include <cstdlib> #include <cstdio> #include <new> struct MyStruct { double *a; MyStruct() : a(NULL) { printf("Default constructor\n"); } MyStruct( double *b )

我写了以下内容,认为它应该在运行时出错。 然而它不是,它运行良好,我不明白为什么

#include <cstdlib>
#include <cstdio>
#include <new>

struct MyStruct
{
    double *a;

    MyStruct()
        : a(NULL) 
        { printf("Default constructor\n"); }
    MyStruct( double *b )
        : a(b) 
        {}
    MyStruct( const MyStruct& other )
    {
        printf("Copy-constructor\n");
        if ( a != NULL && *a != 3.14 )
            a = other.a;
    }
};

int main()
{
    double num = 3.14;
    MyStruct obj( &num );

    void *ptr = ::operator new( sizeof(MyStruct) );
    new (ptr) MyStruct(obj);

    delete (MyStruct*) ptr; // Calls ~MyStruct
}
当我写
void*ptr=::操作符new(sizeof(MyStruct))
当我写
new(ptr)MyStruct(obj)时,如果它像我想的那样工作,我希望它会出错。我认为这相当于
((MyStruct*)ptr)->MyStruct(obj)
。 如果是这样,那么如果(a!=NULL&&*a!=3.14)
应该到达
*a!=3.14和SEGFULT,因为
a
尚未初始化

我的问题是,
a
似乎没有初始化(因为没有输出“默认构造函数”),但前面的构造函数仍然没有初始化。我错过了什么


以下是生成的汇编代码(我不知道如何阅读):


读取尚未初始化的变量是未定义的行为。因此,编译器在赋值之前将指针的值设置为NULL并非不合理,这将导致复制构造函数中的
if
语句出现错误,因此
*a
将永远不会执行

读取尚未初始化的变量是未定义的行为。因此,编译器在赋值之前将指针的值设置为NULL并非不合理,这将导致复制构造函数中的
if
语句出现错误,因此
*a
将永远不会执行

读取尚未初始化的变量是未定义的行为。因此,编译器在赋值之前将指针的值设置为NULL并非不合理,这将导致复制构造函数中的
if
语句出现错误,因此
*a
将永远不会执行

读取尚未初始化的变量是未定义的行为。因此,编译器在赋值之前将指针的值设置为NULL并非不合理,这将导致复制构造函数中的
if
语句出现错误,因此
*a
将永远不会执行

调用placement
new
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用
obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:
printf()
缓冲它的内存,因为在这个构造之后调用
delete(MyStruct*)ptr会导致未定义的行为,即,在非通过非放置
new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)

要正确销毁对象,您需要使用以下方法:

MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);

实际上,在复制构造过程中,
a
的成员也有未定义的行为:成员不是隐式复制的。也就是说,您正在访问复制构造函数中的未初始化内存,该构造函数也可以执行任何它想要的操作。

调用placement
new
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用
obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:
printf()
缓冲它的内存,因为在这个构造之后调用
delete(MyStruct*)ptr会导致未定义的行为,即,在非通过非放置
new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)

要正确销毁对象,您需要使用以下方法:

MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);

实际上,在复制构造过程中,
a
的成员也有未定义的行为:成员不是隐式复制的。也就是说,您正在访问复制构造函数中的未初始化内存,该构造函数也可以执行任何它想要的操作。

调用placement
new
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用
obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:
printf()
缓冲它的内存,因为在这个构造之后调用
delete(MyStruct*)ptr会导致未定义的行为,即,在非通过非放置
new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)

要正确销毁对象,您需要使用以下方法:

MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);

实际上,在复制构造过程中,
a
的成员也有未定义的行为:成员不是隐式复制的。也就是说,您正在访问复制构造函数中的未初始化内存,该构造函数也可以执行任何它想要的操作。

调用placement
new
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用
obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:
printf()
缓冲它的内存,因为在这个构造之后调用
delete(MyStruct*)ptr会导致未定义的行为,即,在非通过非放置
new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)

要正确销毁对象,您需要使用以下方法:

MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);
实际上,
a