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

为什么在C中没有内置函数来查找指针数组的大小?,c,sizeof,C,Sizeof,free()只需要指针值即可释放分配的内存。这意味着C知道分配的内存块有多大。那么,为什么没有一些内置函数来查找指针数组的大小呢 我知道惯例是跟踪数组大小,但是考虑到已经有一些内存管理在本地进行,为什么我们不利用它为数组提供一个方便的size()函数呢?因为基本上,地址将指向包含元数据的内存块(例如块的大小)。释放该项实际上会将块标记为可用(如果指针有效) 如果调用方随后访问该内存位置,则这是未定义的行为。因此,即使从这个角度来看,free也会完成它的工作。这样的功能是可能的。问题是为什么C标准

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


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

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


如果调用方随后访问该内存位置,则这是未定义的行为。因此,即使从这个角度来看,free也会完成它的工作。

这样的功能是可能的。问题是为什么C标准不要求它

GNUC库实现提供了一个类似于您所建议的功能。它返回
malloc()
ed指针的可用字节数——由于各种原因,它可能大于请求的大小

标准中为什么没有这样的功能还不是100%清楚。在1989年的报纸上或是在2008年的报纸上都没有提到

需要记住的一点是,实现不需要跟踪
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\u可用的\u size()
函数类似,仅当参数指向堆分配的数组时才起作用。这意味着函数要么必须假设数组是堆分配的(并且这个假设是正确的!),要么必须得到额外的信息。在后一种情况下,也可以指定数组的大小,使
size()
多余。

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

大多数
malloc()
实现都提供了一个非标准函数来检索分配块的可用大小:在Glibc中,这个函数是
size\t malloc\u usable\u size(void*ptr)。其他库可能有不同的函数或根本没有函数来检索此信息


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

free()只需要指针值,因为您只能传递malloc()返回的指针。malloc()将在返回指针的前地址写入此赋值的大小。当您将指针传递给free()时,free()将读取大小,因此free()知道要释放多少空间。因此,没有使用任何函数来查找指针数组的大小。

因为没有人设计和提出这样的功能。我预计会存在可实施性问题。但也要想一想,并不是每个指针都是malloc的结果,因此您会有一个不可诊断的前提条件。相关:
sizeof
是编译时特性
free
是一个运行时函数。由于舍入和细分,该功能几乎没有用处。例如,如果您
malloc(3)
,大多数实现将返回一个16字节的块。
free
函数只知道指针代表1个内存块。它不记得你要了3个字节。另一方面,您可以
malloc(1024)
然后将该内存用于每个256字节的4个数组。建议的
size()
函数无法知道如何细分内存。@hazrmard:例如:
int array1[10];国际阵列2[20];int*ptr=rand()%2?阵列1:阵列2。无法知道数组有多大