用new创建的C ++对象,用free()销毁;这有多糟糕?

时间:2010-10-31 01:58:39

标签: c++ memory-management

我正在修改一个相对较大的C ++程序,不幸的是,我之前是否有人使用C或C ++语法(这是在大学的电气工程系,我们的EE总是很想使用)并不总是很清楚C代表一切,不幸的是,在这种情况下,人们实际上可以逃脱它。)

但是,如果有人创建了一个对象:

Packet* thePacket = new Packet();

是否使用delete thePacket;free(thePacket);销毁了

是否重要?

我意识到delete会调用析构函数而free()不会,但Packet没有析构函数。我在这里陷入了记忆管理沼泽的可怕时间,我认为这可能是许多问题之一。

6 个答案:

答案 0 :(得分:49)

是的,这很重要。

对于使用new获得的内存,必须使用delete

对于使用malloc获得的内存,必须使用free

newmalloc可以在内部使用不同的数据结构来跟踪它分配内存的内容和位置。因此,为了释放内存,您必须调用知道这些数据结构的相应函数。然而,在一段代码中混合这两种类型的内存分配通常是个坏主意。

答案 1 :(得分:27)

如果您致电free(),则不会调用析构函数。

此外,还有no guarantee that new and free operate on the same heap.

您还可以覆盖newdelete以专门针对特定课程进行操作。如果您这样做,但请拨打free()而不是自定义delete,那么您会错过您在delete中写入的任何特殊行为。 (但如果你这样做,你可能不会问这个问题,因为你知道你错过了什么行为......)

答案 2 :(得分:6)

Packet有一个析构函数,即使你没有明确声明一个析构函数。它有一个默认的析构函数。默认的析构函数可能实际上并没有做太多,但你不能指望这种情况。这取决于编译器的作用。

newmalloc也可能有完全不同的实现。例如,总是在上下文中调用delete,在上下文中,delete具有关于它在编译时删除的数据结构大小的完美信息。 free没有这种奢侈。 new正在使用的分配器可能不会将字节存储在内存区域的开头,表明它占用了多少字节。这会导致free完全做错事,并在释放使用new分配的内容时崩溃您的程序。

就个人而言,如果让人们做正确的事情或自己修理代码是完全不可能的,我会声明我自己的全球operator new,其中有malloc,所以free肯定不会崩溃,即使它仍然不会调用析构函数并且通常非常难看。

答案 3 :(得分:4)

你是对的,正确。正如你自己所说,free将不会调用析构函数。即使Packet没有明确的析构函数,它也使用了一个继承的析构函数。

在使用free创建的对象上使用new就像只破坏浅拷贝到达的对象。深度破坏需要析构函数。

另外,我不确定使用new()创建的对象与malloc()内存在同一个内存映射中。我认为不能保证它们。

答案 4 :(得分:4)

简而言之,它与未定义的行为一样糟糕。

这是安静的自我解释。

  

C标准($ 7.20.3.2 / 2) - “免费   函数导致指向的空间   由ptr解除分配,即   可供进一步分配。   如果ptr是空指针,则不执行任何操作   发生。否则,如果是参数   与之前的指针不匹配   由calloc,malloc或者返回   realloc函数,或者如果空间有   通过免费或免费电话取消分配   realloc,行为未定义。“

答案 5 :(得分:2)

  

如果有人创建了一个对象:

Packet* thePacket = new Packet();
     

是否使用delete thePacket销毁是否重要;或免费(thePacket); ?

是的,这很重要。 free (thePacket)将调用未定义的行为,但delete thePacket不会,我们都知道未定义的行为可能会带来灾难性的后果。