free()
只需要指针值来释放已分配的内存。这意味着C知道分配的内存块有多大。那么为什么没有一些内置函数来查找指针数组的大小?
我知道惯例是跟踪数组大小,但鉴于已经有本地发生了一些内存管理,为什么我们不利用它来为数组提供方便的size()
函数?
答案 0 :(得分:6)
这样的功能是可能的。问题是为什么C标准不要求它。
GNU C库实现提供的函数malloc_usable_size()
与您的建议类似。它返回malloc()
ed指针的可用字节数 - 由于各种原因,它可能大于请求的大小。
为什么标准中没有这样的功能,这并不是100%清楚。它没有在1989年ANSI C Rationale或ISO C99 Rationale中提及。
要记住的一件事是,实现不需要来跟踪malloc()
调用所请求的字节数。它通常会将请求汇总到更大的值,并且只需要跟踪它。
就此而言,free()
不一定需要知道被解除分配的块的大小。它可能只是调用一些不提供该信息的低级函数。或者,例如,已分配的块可以组织成链接列表,每个分配的大小一个列表; free()
可能只是从该列表中释放一个块而不必知道大小。
最后,C程序员几十年来一直没有这样的功能。添加提供它的要求会对所有实现施加一些(可能相当小的)开销。我认为态度是你可以简单地记住你要求的内存量,并根据需要使用这些信息。
如果您分配单个对象:
some_type *ptr = malloc(sizeof *ptr);
然后sizeof *ptr
为您提供对象的大小。如果你分配一个数组:
some_type *ptr = malloc(count * sizeof *ptr);
然后sizeof *ptr
仅为您提供已分配数组的单个元素的大小 - 但如果您记住count
的值,则可以轻松地计算所请求的总大小。
底线:C标准可能需要这样的功能,但实际上并不是必需的。
更新:Kerrek SB在评论中提出了一个很好的观点,这是我没想过的。我将冒昧地在这里总结一下。
通过指向其初始元素的指针对数组进行操作的函数(并且这些函数有 lot )不应该关心如何分配数组。建议的size()
函数(如GNU特定的malloc_usable_size()
)仅在参数指向堆分配的数组时才起作用。这意味着该函数必须假设该数组是堆分配的(并且对于该假设是正确的!)或者给出额外的信息。在后一种情况下,也可以给出数组的大小,使size()
变得多余。
答案 1 :(得分:2)
free()
可能会使用内部数据来回收正在发布的内存块,但请注意,此数据不一定包含传递给malloc()
,calloc()
或{的确切大小{1}}分配块。 C标准没有指定检索此信息的函数。
大多数realloc()
实现提供了一个非标准函数来检索已分配块的可用大小:在Glibc中,此函数为malloc()
。其他库可能具有不同的功能或根本没有功能来检索此信息。
对于检索具有指针的数组大小的通用解决方案,这通常是不可能的。在有效的实现中,指针不携带大小信息。可以实现携带此信息的胖指针,但整个系统需要以这种方式编译。某些集成编译器(如size_t malloc_usable_size(void *ptr);
)支持此方法以提供运行时指针检查。
答案 2 :(得分:0)
因为基本上,地址将指向一块内存,其中包含元数据(例如块的大小)。释放该条目实际上将标记块可用(如果指针有效)。
如果调用者之后访问该内存位置,则表示该未定义的行为。所以即使从这个角度来看,自由也会完成它的工作。
答案 3 :(得分:0)
free()只需要指针值,因为你只能传递malloc()返回的指针。malloc()会在返回指针的前端地址中写出这个赋值的大小。当你将指针传递给free(),free()将读取大小,因此free()知道要释放多少空间。因此,没有使用任何函数来查找指针数组的大小。