【问题标题】:What's the outcome if I use free with new or delete with malloc?如果我将 free 与 new 一起使用或与 malloc 一起使用 delete,结果是什么?
【发布时间】:2010-03-28 22:27:44
【问题描述】:

是编译器错误还是运行时错误?下面的代码可以编译!

class Base{
void g();
void h();
};

int main()
{
    Base* p = new Base();
    free(p);
return 0;
}

但是如果我这样声明类 Base 就不能用虚函数编译

class Base{
virtual void g();
void h();
};

无论函数是不是虚函数,下面的代码都可以一直编译。

class Base{
void g();
void h();
};

int main()
{
    Base* p = (Base*)malloc(sizeof(Base));
    delete p;
return 0;
}

【问题讨论】:

  • 结果是程序没有定义的行为。
  • @avakar,为什么不将其发布为答案?
  • @Poita - 显然他希望 me 获得分数 ;-)
  • 您还应该使用 reinterpret_cast 而不是您使用的 c 样式转换。

标签: c++ memory-management malloc new-operator


【解决方案1】:

未定义的结果,加上 malloc() 不调用构造函数和 free() 不调用析构函数。

【讨论】:

  • 由于行为是未定义的,free()可以调用析构函数,如果你传递一个用new分配的指针。我同意“它没有”,因为我怀疑它是否有任何实现。
  • 是的,但是你也面临着new分配的内存不保证与free兼容的问题。同上 malloc 和删除。
【解决方案2】:

正如评论所说 - 结果是程序的行为未定义。

如果你有 "new" 和 "free",你的析构函数不会被调用。这通常会导致内存和资源泄漏。

如果你有“malloc”和“delete”,你不会得到构造函数调用,所以你的对象是未初始化的。这可能导致各种错误,例如当调用析构函数时。

正如下面的评论所指出的,在非 POD 类型(例如具有虚拟方法的类和使用虚拟继承的类)中,有些东西需要初始化,即使需要构造函数初始化并不是很明显。如果你 malloc 一个对象然后调用一个虚方法,最有可能的结果是你的程序会崩溃。

到目前为止,如果您的所有类型都是 POD(普通旧数据),您可能会很幸运,但这在很大程度上取决于您的编译器 - 不能保证“malloc”和“new”使用相同的堆,所以您可以在某些编译器上出现堆损坏和崩溃。

简而言之 - 不要这样做。

【讨论】:

  • 你是对的,但在实践中,我从未遇到过不使用 malloc/free 为全局 new/malloc 分配内存的编译器——当然这不能依赖上
  • POD类型不能有虚函数,所以第二个不是POD类型。
  • @James - 我在描述一般原则。正如您所说,虚函数清楚地证明了该类型不是 POD,而 malloc 的明显问题是虚指针未初始化,因此对后期绑定方法的调用将崩溃。
【解决方案3】:

这是未定义的行为。这意味着任何事情都可能发生 - 程序可能成功,它可能会严重崩溃,它可能会默默地失败并在很久以后在一段无关紧要的看似无辜的代码中崩溃,或者它甚至可能会擦除您的硬盘驱动器。

任何事情都可能发生,因为您正在做 C++ 标准不允许做的事情。

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 1970-01-01
    • 2017-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多