删除是如何工作的?

7

可能重复:
C编程:free如何知道要释放多少字节?

delete 如何知道需要释放多少字节?我读到过一些在指针地址之前的块中包含了块地址细节。这里是否有人知道这个块包含多少字节或该块的格式是什么?

3个回答

7
通常情况下,这是与实现相关的。一般的实现方式是,new/malloc将分配比您请求的字节数稍多的字节,并将额外的字节用于一些簿记:很多时候,分配的块也将在链接列表中保持,因此额外的字节将用于存储下一个/上一个指针,以及块的大小。
然而,这不是强制性的。new/malloc调用同样可以将您的指针和块的大小存储在例如映射中。
如果您对特定实现感兴趣,您需要提供更多信息(例如您正在使用什么运行时/编译器)。

1

new 运算符和 malloc 函数以它们自己特定的方式处理内存,所以:

  • 如果你使用 'new' 分配了内存,则使用 'delete' 进行释放
  • 如果你使用 'malloc' 分配了内存,则使用 'free' 进行释放
  • 如果你不知道内存是如何/由谁/在哪里分配的,请不要对其进行释放

如果你试图干涉 mallocnew 的内部工作(似乎这是你的目标),那么你正在错误地进行 ^^


1

这个问题没有一个单一的正确答案,因为它取决于情况。在某些情况下,编译器在编译时知道对象的大小,因此 delete 知道要释放多少字节。在内存大小在编译时未知的情况下,可能涉及到内存映射,或者像你自己建议的那样,在指针之前有一个单词,告诉分配的字节数。

我认为很多东西都是实现特定的,不能依赖于特定的方式。这个问题与 one 非常相似。


你确定关于“在某些情况下,编译器在编译时知道对象的大小,因此delete知道要释放多少字节”的部分吗?我不认为这是可能的,即使它是,也需要系统能够以两种不同的方式在堆上分配东西。 - Lindydancer
@Lindydancer - 当然可以!而且这没有任何问题。例如,sizeof关键字用于确定编译时对象的大小。编译器根据分配或释放的类型生成不同的代码也不是特别牵强。所有这些都是具体实现相关的。 - John Leidegren
@John - 我问这个问题的原因是因为我已经写了10多年的C/C++编译器,而我从未见过这种情况。由于需要一个特殊的delete运算符来获取大小(而不是通过指针获取),编译器必须能够找到所有对new的调用以及相应的delete调用。该指针不能逃逸并且不能被普通的delete删除,而这个特殊的delete也不能删除普通指针。你有哪个编译器的具体例子可以做到这一点吗? - Lindydancer
@Lindydancer - 我的C/C++并不完美,但只要您不使用malloc来分配对象,那么类似这样的代码就可以工作。但是,在C/C++中,指针没有特定类型或被锁定为具有特定类型的概念,我知道您可以使用RTTI进行某些类型测试,但我不知道这是否涉及此类对象的实际内存管理。 - John Leidegren
@Lindydancer - 无论如何,RTTI与编译时相反,我想你是对的。C++中的内存管理是显式的,而我已经被托管代码宠坏了太久。 - John Leidegren
谢谢你的有趣讨论。尽管如此,寻找处理事情的新方法总是很有趣的,即使这可能不可行。 - Lindydancer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接