我正在修改一个相对较大的C ++程序,不幸的是,我之前是否有人使用C或C ++语法(这是在大学的电气工程系,我们的EE总是很想使用)并不总是很清楚C代表一切,不幸的是,在这种情况下,人们实际上可以逃脱它。)
但是,如果有人创建了一个对象:
Packet* thePacket = new Packet();
是否使用delete thePacket;
或free(thePacket);
销毁了
我意识到delete会调用析构函数而free()不会,但Packet没有析构函数。我在这里陷入了记忆管理沼泽的可怕时间,我认为这可能是许多问题之一。
答案 0 :(得分:49)
是的,这很重要。
对于使用new
获得的内存,必须使用delete
。
对于使用malloc
获得的内存,必须使用free
。
new
和malloc
可以在内部使用不同的数据结构来跟踪它分配内存的内容和位置。因此,为了释放内存,您必须调用知道这些数据结构的相应函数。然而,在一段代码中混合这两种类型的内存分配通常是个坏主意。
答案 1 :(得分:27)
如果您致电free()
,则不会调用析构函数。
此外,还有no guarantee that new
and free
operate on the same heap.
您还可以覆盖new
和delete
以专门针对特定课程进行操作。如果您这样做,但请拨打free()
而不是自定义delete
,那么您会错过您在delete
中写入的任何特殊行为。 (但如果你这样做,你可能不会问这个问题,因为你知道你错过了什么行为......)
答案 2 :(得分:6)
Packet
有一个析构函数,即使你没有明确声明一个析构函数。它有一个默认的析构函数。默认的析构函数可能实际上并没有做太多,但你不能指望这种情况。这取决于编译器的作用。
new
和malloc
也可能有完全不同的实现。例如,总是在上下文中调用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
不会,我们都知道未定义的行为可能会带来灾难性的后果。