为什么C标准库没有提供知道分配内存大小的函数?

tro*_*813 2 c memory size malloc memory-management

当通过调用动态分配一定量的内存时malloc(),操作系统内部会以某种方式存储分配的内存量(以跟踪已使用的内存等),因此我们仅在free()不再需要该内存块时提供指针。

但是,我们无法以可移植且与操作系统/编译器无关的方式检索只有指针的大小。也存在一些不可移植的方式类似_msize在Windows /的Visual C,或malloc_usable_size在glibc的。因此,唯一的方法仍然是传播所有需要的大小以及相应的指针等,这很容易出错。

所以,问题是:为什么 C 标准开发人员决定不在标准中包含可移植功能?

PS 问“为什么”可能是不恰当的,因为它通常至少在某种程度上涉及基于意见的事情,但在这里我相信有一些基本的理由这样做。

Ste*_*ell 5

因为你可以得到指向malloc和朋友没有返回的东西的指针。

int x = 10;
int * p = &x;
Run Code Online (Sandbox Code Playgroud)

您正在谈论的功能必须弄清楚是否pmalloc(可能很昂贵)返回。如果不是(如在这种情况下),则无法知道分配的空间量。如果您得到一个指向由 分配的内容的指针malloc,而不是由 分配的确切指针,您也会遇到问题malloc

int * p = malloc(sizeof(int) * 10);
int * p2 = p + 5;
Run Code Online (Sandbox Code Playgroud)

如果我询问 的大小,正确的结果是p2什么?

更一致的方法包括在需要的地方传递大小。这使您可以使用地址而不管它们来自何处,包括对某些内存块的偏移量(例如,数组,就像我在p2上面所做的那样)。


chq*_*lie 5

malloc()不存在阻止 C 标准委员会添加新库函数来检索可通过、calloc()realloc()aligned_alloc()strdup()任何类似函数先前返回的有效指针访问的字节数的技术问题。返回的数字不一定是最初传递给分配函数的大小,并且可以想象该信息可能根本不可用,因此返回值 表示0该信息不可用。

尚未添加此类功能的原因可能是 C 标准委员会通常非常不愿意添加新功能。例如,尽管几十年来strdup()大多数 C 库都提供了一致的实现,但它还是花了 30 多年的时间才最终进入 C 标准(它将成为下一版本的一部分)。

对于之前未由内存分配函数返回或已释放的任何指针,此函数将具有未定义的行为,就像freeor一样realloc。是否定义为NULL是有争议的,但返回值似乎0在这种情况下是合适的。如果大小未知(对于不存储此信息的虚拟分配器来说这是可能的),则返回值0也将指示此情况。

malloc_usable_size以下是GNU lib C 中的手册页摘要:

姓名

malloc_usable_size- 获取从堆分配的内存块的大小

概要

   #include <malloc.h>
    
   size_t malloc_usable_size(void *ptr);
Run Code Online (Sandbox Code Playgroud)

描述

malloc_usable_size() 函数返回 所指向的块中的可用字节数、指向由或相关函数ptr分配的内存块的指针。malloc(3)

返回值

malloc_usable_size()返回 指向的已分配内存块中的可用字节数 ptr。如果ptrNULL0则返回。

属性

多线程(参见参考资料pthreads(7)):该malloc_usable_size()函数是线程安全的。

符合

该函数是 GNU 扩展。

笔记

由于对齐和最小大小限制,返回的值malloc_usable_size()可能大于请求的分配大小。尽管应用程序可以覆盖多余的字节而不会产生不良影响,但这不是良好的编程实践:分配中的多余字节数取决于底层实现。

该功能的主要用途是用于调试和自省。

也可以看看

malloc(3)