为什么 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,没有使用任何函数来查找大小指针数组。
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,没有使用任何函数来查找大小指针数组。