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
将永远不会执行 调用placementnew
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:printf()
缓冲它的内存,因为在这个构造之后调用delete(MyStruct*)ptr会导致未定义的行为代码>,即,在非通过非放置new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)
要正确销毁对象,您需要使用以下方法:
MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);
实际上,在复制构造过程中,a
的成员也有未定义的行为:成员不是隐式复制的。也就是说,您正在访问复制构造函数中的未初始化内存,该构造函数也可以执行任何它想要的操作。调用placementnew
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:printf()
缓冲它的内存,因为在这个构造之后调用delete(MyStruct*)ptr会导致未定义的行为代码>,即,在非通过非放置new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)
要正确销毁对象,您需要使用以下方法:
MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);
实际上,在复制构造过程中,a
的成员也有未定义的行为:成员不是隐式复制的。也就是说,您正在访问复制构造函数中的未初始化内存,该构造函数也可以执行任何它想要的操作。调用placementnew
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:printf()
缓冲它的内存,因为在这个构造之后调用delete(MyStruct*)ptr会导致未定义的行为代码>,即,在非通过非放置new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)
要正确销毁对象,您需要使用以下方法:
MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);
实际上,在复制构造过程中,a
的成员也有未定义的行为:成员不是隐式复制的。也就是说,您正在访问复制构造函数中的未初始化内存,该构造函数也可以执行任何它想要的操作。调用placementnew
没有问题:它应该有什么问题:它有足够的内存将对象放入其中。当然,它应该使用copy构造函数,因为您使用obj
作为参数调用它。尽管如此,这个输出是否出现仍然是个未知数:printf()
缓冲它的内存,因为在这个构造之后调用delete(MyStruct*)ptr会导致未定义的行为代码>,即,在非通过非放置new
获得的指针上,在库刷新缓冲区之前,代码可能很容易崩溃(它打印出复制构造函数已在我的系统上使用)
要正确销毁对象,您需要使用以下方法:
MyStruct* mptr = new(ptr) MyStruct(obj);
mptr->~MyStrucT();
operator delete(ptr);
实际上,a