为什么 C 中没有内置函数来查找指针数组的大小?

Why is there no built-in function to find the size of a pointer array in C?

free() 只需要指针值来释放分配的内存。这意味着 C 知道分配的内存块有多大。那怎么没有一些内置函数来查找指针数组的大小呢?

我知道惯例是跟踪数组大小,但鉴于本机已经进行了一些内存管理,为什么我们不利用它为数组提供一个方便的 size() 函数?

因为基本上,地址将指向一块内存,其中包含元数据(例如块的大小)。释放该条目实际上会将块标记为可用(如果指针有效)。

如果调用者之后访问该内存位置,那是未定义的行为。所以即使从这个角度来看,free 也会完成它的工作。

这样的功能是可以实现的。问题是为什么 C 标准不需要它。

GNU C 库实现提供了一个函数 malloc_usable_size(),它与您所建议的类似。它 returns malloc()ed 指针的可用字节数 -- 由于各种原因,它可能大于请求的大小。

目前还不是 100% 清楚为什么标准中没有这样的功能。 1989ANSI C Rationale or in the 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 在评论中提出了一个很好的观点,这是我没有想到的。我冒昧的总结一下。

通过指向其初始元素的指针对数组进行操作的函数(并且有 很多 此类函数)不必关心数组是如何分配的.提议的 size() 函数与 GNU 特定的 malloc_usable_size() 一样,仅在参数指向堆分配数组时才起作用。这意味着该函数要么必须 假设 数组是堆分配的(并且该假设是正确的!),要么被提供额外的信息。在后一种情况下,还不如给定数组的大小,使 size() 变得多余。

free() 可能会使用内部数据来回收正在释放的内存块,但请注意,此数据不一定包含传递给 malloc()calloc() 的确切大小,或 realloc() 分配块。 C 标准未指定检索此信息的函数。

大多数 malloc() 实现提供了一个非标准函数来检索分配块的可用大小:在 Glibc 中,此函数是 size_t malloc_usable_size(void *ptr);。其他图书馆可能具有不同的功能或根本没有检索此信息的功能。

至于检索您拥有指针的数组大小的通用解决方案,这通常是不可能的。在有效的实现中,指针不携带大小信息。可以实现携带此信息的 fat pointers,但整个系统需要以这种方式编译。 tcc 等一些集成编译器支持这种方法以提供运行时指针检查。

free()只需要指针值,因为你只能传递指针,malloc() return.The malloc()会把本次assign的大小写在return的前面地址pointer.When 你把指针传递给 free(),free() 会读取大小,所以 free() 知道有多少 space 到 release.Therefor,没有使用任何函数来查找大小指针数组。