我将首先用C ++发布我的测试程序:
#include <iostream>
using namespace std;
class X
{
int x;
public:
X()
{
cout<<"constructing\n";
x=0;
}
int& getx()
{
return x;
}
~X()
{
cout<<"destroying\n";
}
};
int main()
{
X* p=(X*)malloc(sizeof(X));
++p->getx();
p->getx()*=5;
cout<<p->getx();
free(p);
return 0;
}
输出:
5
现在,在有人抱怨为什么我使用malloc
&amp;在{+ 1}} C ++程序中,我想重申它只是一个测试程序,即使使用free
&amp; operator new
。但我的问题仍然是:
operator delete
没有创建X的对象,我们如何才能访问类X的变量x?malloc or operator new
也不会破坏对象并执行纯粹的分配。如果我使用free & operator delete
创建对象但使用new
而不是operator delete or free
会发生什么?我的目标是否仍然在那里&amp;它还可以使用吗?答案 0 :(得分:12)
如果通过调用new
解除分配使用free()
创建的对象,则您将深入到未定义的行为。同样,如果您使用malloc()
取消分配delete
&lt; ed}对象,则表示您有未定义的行为。无论你做什么,都不要混淆两者。
malloc()
具有与new
不同的语义:malloc()
只分配内存,不调用构造函数。 new
执行分配,并调用适当的构造函数。
同样,free()
和delete
之间存在模拟差异:delete
在释放内存之前调用析构函数,free()
没有。
您可以在C ++中使用malloc()
来支持真正的C ++对象,但您必须自己进行构造函数/析构函数调用:
//The placement-new below needs this:
#include <new>
//This is what new does:
char* temp = (char*)malloc(sizeof(Foo)); //allocation only
Foo* foo = new(temp) Foo(); //placement-new: construction only
//This is what delete does:
foo->~Foo(); //destruction only
free((void*)foo); //deallocation only
请注意,第二行中的placement-new语法是在C ++中显式调用构造函数的唯一方法。可以像任何其他成员一样显式调用析构函数。这种不对称的原因是对象在销毁之前确实是一个有效的对象,而在构造之前并不是这样。
关于p->getx()
编译原因的问题。这取决于您的代码中的这个小演员:
X* p=(X*)malloc(sizeof(X));
^
|
this little cast
在这里,程序员明确地告诉编译器:&#34;我知道我给你的值看起来不像指向X
,但我告诉你它是。所以,愚蠢的编译器,只是关闭类型不匹配,并将其视为指向X
的指针,因为我,人类,你的上帝,告诉你了!&#34;
那么你的编译器能做些什么呢?它会关闭类型不匹配,并将指针视为指向X
的指针,正如您所说的那样。如果这是错的,这就是你的问题。也许程序运行正常,也许它会崩溃,也许它会默默地破坏数据,也许会出现粉红色的大象。你的编译器不关心。唯一关心的是它是你的愿望。编译器可以非常听话。
答案 1 :(得分:3)
回答这部分问题:“如果我使用new创建一个对象但使用operator delete或free而不是删除会发生什么?我的对象是否仍然在那里&amp;它仍然可用吗?”
使用malloc
分配并使用delete
释放是未定义的行为。在调用对象的析构函数后,无法保证实现将使用C free
。
同样相反。如果使用new
进行分配,则无法保证返回的指针来自内部调用的malloc
,realloc
或calloc
,只有通过它才能安全通过的情况指向free
的指针。
即使它有效,也可能会破坏程序和/或泄漏资源,因为你要么跳过对象的构造函数或析构函数。
编辑:
你说“显然免费&amp;运营商删除也不会破坏对象并执行纯粹的分配。”嗯,那是错的。 delete
将调用object的析构函数,因此它将销毁然后解除分配。
至于评论中澄清的问题,“为什么你仍然可以访问x”,好吧,malloc
将分配对象占用的全部空间(在你的情况下,我认为只是x
变量),变量将在那里,只有构造函数不会被调用,因此,它的值不会被设置为零。如果你在运行程序时最初为零,那只是巧合。
答案 2 :(得分:1)
从这么多人那里读了很多分,我自己写了一个程序来解释你的问题。见下文: -
p
了解v
如何忽略了向量executed
并转到了行vector<int>
。这是因为class
永远不是由class template
创建的operator new (or malloc in your case)
(或更确切地说是x
)。你的程序显示了operator new or malloc
的输出,因为它是一个原始类型&amp;不是一个班级。对于一个类,你需要一个构造函数&amp;因此operator new with new
不适合课程和课程。因此输出。如果您只是替换operator delete with delete
&amp; constructing
5
1 2
executed
destroying
然后输出将是: -
malloc & free
现在你的代码给出了正确的&amp;合适的结果!刚果!
对于你的第二个问题,永远不要与new & delete
混淆public class AllProductsCategoryPage extends BasePage{
public AllProductsCategoryPage(WebDriver driver) {
super(driver);
}
public void getData() throws InterruptedException {
List<String> prices;
}
}
,因为它会创建UB并且不会发生结果。