C++ 为什么可以';我们不能释放new分配的()内存吗?

C++ 为什么可以';我们不能释放new分配的()内存吗?,c++,memory-management,new-operator,C++,Memory Management,New Operator,我知道free()不会调用析构函数,但是除了成员变量不能正确析构函数之外,还会导致什么呢 另外,如果我们删除由malloc分配的指针会怎么样?一个重要的区别是new和delete还调用对象的构造函数和析构函数。因此,您可能会出现意外的行为。这是我认为最重要的事情。因为它可能不是同一个分配器,这可能会导致奇怪的、不可预测的行为。另外,您根本不应该使用malloc/free,并避免在不必要的地方使用new/delete 我知道free()不会调用析构函数 这就是不这样做的充分理由 P>另外,对于C

我知道
free()
不会调用析构函数,但是除了成员变量不能正确析构函数之外,还会导致什么呢


另外,如果我们
删除
malloc
分配的指针会怎么样?

一个重要的区别是new和delete还调用对象的构造函数和析构函数。因此,您可能会出现意外的行为。这是我认为最重要的事情。

因为它可能不是同一个分配器,这可能会导致奇怪的、不可预测的行为。另外,您根本不应该使用malloc/free,并避免在不必要的地方使用new/delete

我知道free()不会调用析构函数

这就是不这样做的充分理由


<> P>另外,对于C++代码实现,即使使用相同的内存区域,也不需要使用相同的内存区域:“Mulalc < /COD>”和“代码>新< /代码>,因此可能是试图从一个完全不同的竞技场释放内存,几乎肯定会致命的东西。

是否在引擎盖下使用
malloc
取决于实现。将
new
free
malloc
delete
混合使用完全取决于实现——可以编写一个实际工作正常的实现。但是不能保证
new
分配的内存池与
free()
要将内存返回的内存池相同。假设
malloc()
new
在每个分配的块的开头使用几个字节的额外内存来指定块的大小。此外,假设
malloc()
new
对该信息使用不同的格式——例如,
malloc()
使用字节数,而
new
使用4字节长的字数(仅为示例)。现在,如果您使用
malloc()
进行分配,并使用
delete
进行释放,则
delete
所需的信息将无效,并且最终会导致堆损坏。

许多要点:

  • 这是一种未定义的行为,因此具有内在的风险,随时都可能发生变化或破坏,而且毫无理由
  • (如您所知)
    delete
    调用析构函数,而
    free
    不会。。。你可能有一些POD类型而不在乎,但是其他人很容易在该类型中添加一个
    字符串
    ,而没有意识到它的内容有奇怪的限制
  • 如果您
    malloc
    并忘记使用placement
    new
    在其中构造对象,然后调用成员函数,就像对象存在一样(包括调用析构函数的
    delete
    ),成员函数可能会尝试使用带有垃圾值的指针进行操作
  • new
    malloc
    可能从不同的堆中获取内存
  • 即使如果
    调用
    malloc
    来获取其内存,那么
    new
    /
    delete
    和底层
    malloc
    /
    free
    行为之间也可能没有1:1的对应关系。
      >代码>新< /C>可能有额外的逻辑,例如小对象优化,它对典型C++程序是有益的,但对典型的C程序有害。
  • 有人可能会过载
    new
    ,或链接到调试版本的
    malloc
    /
    realloc
    /
    free
    ,如果您没有正确使用这些功能,任何一个都可能会断开
  • ValGrind、Purify和Insure等工具将无法区分故意怀疑和意外怀疑
  • 在数组的情况下,
    delete[]
    调用所有析构函数,
    free()
    不会调用,但是堆内存通常有一个数组大小的计数器(例如,对于32位VC++2005发行版,数组大小在
    new[]可见返回的指针值之前的4个字节)
    。对于POD类型(不适用于VC++2005),这个额外的值可能存在,也可能不存在,但如果它是
    free()
    ,则肯定不会出现这种情况。并非所有堆实现都允许释放从
    malloc()
    返回的值移位的指针

甚至是同一编译器的同一版本,但编译是在blue moon:-)期间完成的,甚至是同一个编译会话,但在不同的代码单元中。或相同的代码单元。或者相同的功能。这是未定义的行为,宝贝!它真的是“实现定义”的吗?我猜它是未定义的,这与“实现定义的”非常不同。@JesperE:我从来没有说过行为(总体)是实现定义的。它实际上没有定义。是否使用malloc是由实现定义的,这就是我在我的文章中提到的answer@Prasoon:因此编译器必须指定malloc是否使用new?听起来很奇怪,最好的观点。仅针对普通的旧数据,人们可以考虑它。但是为什么要这样做呢+1.如果我向你借1000000美元(读作:1MB),然后还其他人而不是你,你会生气吗?这里也有同样的问题,只是现在收件人很生气P