c ++ malloc和自由对象的创建和删除

Ank*_*rya -5 c++ malloc free

我将首先用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.但我的问题仍然是:

  1. 即使没有创建X的对象,malloc or operator new我们如何访问类X的变量x?
  2. 显然,free & operator delete也不要破坏对象并执行纯粹的分配.如果我new使用operator delete or free而不是使用而创建一个对象会发生什么delete?我的对象是否仍然存在并且仍然可用吗?

cma*_*ter 13

  1. 如果取消分配new通过调用创建的对象free(),则您将深入到未定义的行为.同样,如果您释放malloc()'ed对象delete,则表示您有未定义的行为.无论你做什么,都不要混淆两者.

  2. 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,就像你告诉它的那样.如果这是错的,那就是你的问题.也许程序运行正常,也许它会崩溃,也许它会默默地破坏数据,也许会出现粉红色的大象.你的编译器不关心.只关心它是你的愿望.编译器可以非常听话.

  • @AnkitAcharya:很简单; C没有类,因此没有构造函数(或成员函数).在C中使用`struct`类型时,所有`p-> x`(例如)都访问适当的内存位置. (3认同)