我将首先用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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
5
Run Code Online (Sandbox Code Playgroud)
现在,在任何人抱怨为什么我在C++程序中使用malloc&之前free,我想重申它只是一个测试程序,即使使用operator new&也可以完成上述操作operator delete.但我的问题仍然是:
malloc or operator new我们如何访问类X的变量x?free & operator delete也不要破坏对象并执行纯粹的分配.如果我new使用operator delete or free而不是使用而创建一个对象会发生什么delete?我的对象是否仍然存在并且仍然可用吗?cma*_*ter 13
如果取消分配new通过调用创建的对象free(),则您将深入到未定义的行为.同样,如果您释放malloc()'ed对象delete,则表示您有未定义的行为.无论你做什么,都不要混淆两者.
malloc()有不同的语义new:malloc()只是分配内存,它不会调用构造函数.new进行分配,并调用适当的构造函数.
同样,free()和之间存在模拟差异delete:delete在释放内存之前调用析构函数,free()而不是.
您可以malloc()在C++中使用它来支持真正的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
Run Code Online (Sandbox Code Playgroud)
请注意,第二行中的placement-new语法是在C++中显式调用构造函数的唯一方法.可以像任何其他成员一样显式调用析构函数.这种不对称的原因是对象在破坏之前确实是一个有效的对象,而在构造之前并不是这样.
关于为什么要p->getx()编译的问题.这归结为代码中的这个小演员:
X* p=(X*)malloc(sizeof(X));
^
|
this little cast
Run Code Online (Sandbox Code Playgroud)
在这里,你,程序员,明确地告诉编译器:"我知道我给你的值看起来不像指针X,但我告诉你它是.所以,愚蠢的编译器,只是关闭类型不匹配,并把它当作指针X,因为我,人类,你的上帝,告诉你了!"
那么你的编译器能做些什么呢?它会关闭类型不匹配,并将指针视为指针X,就像你告诉它的那样.如果这是错的,那就是你的问题.也许程序运行正常,也许它会崩溃,也许它会默默地破坏数据,也许会出现粉红色的大象.你的编译器不关心.只关心它是你的愿望.编译器可以非常听话.