确定在堆中分配的缓冲区大小

4

我想知道使用callocbyte中分配的缓冲区大小。通过在我的机器上测试以下内容:

double *buf = (double *) calloc(5, sizeof(double));
printf("%zu \n", sizeof(buf));

即使我只更改一个元素,结果仍为8。我的问题是:
  1. 这是否意味着我只能将8乘以5以获取缓冲区大小(我认为 sizeof 将返回40)?
  2. 如何创建一个宏以返回缓冲区的大小(要检查的缓冲区可以是 charintdoublefloat)?
欢迎提出任何想法。

Calloc() 调用 malloc(),malloc.c 代码超过 5,322 行,因此并不是简单的。但是(没有进行研究),我相信在缓冲区开始之前有一个计数值。这对我来说很有意义,因为 free() 不知道 calloc() 使用的参数。 - Marichyasana
@Marichyasana,你的评论并不是关于[tag:c],而是关于某个(假设的?)实现。实现可以自由选择如何存储free()所需的信息。一个专用的大小字段并不是必要的,事实上,只有指向下一个块的指针可能更容易实现。当然,你可以实现自己的替代malloc(),还提供一些sizeOfChunk()函数,但那将是语言的扩展。而且,顺便说一句,这是毫无意义的,分配一个块的程序知道大小(它将其传递给分配函数)。 - user2371524
2个回答

6

引用 C11,章节 §6.5.3.4,(强调为本人所加)

sizeof 运算符返回其操作数的大小(以字节为单位),其操作数可以是表达式或类型名称括在括号内。 大小由操作数的类型确定。 [...]

因此,使用 sizeof 无法获取指针所指向的内存位置的大小。您需要自己跟踪它。

更详细地说,您的情况相当于 sizeof(double *),这基本上给出了指向双精度浮点数的指针的大小,根据您的环境而定。

没有通用或直接的方法来从内存分配器函数中获取分配的内存大小。但是,您可以使用哨兵值来标记已分配缓冲区的结尾,并使用循环检查该值,但这意味着

  • 必须分配一个额外元素来保存哨兵值本身
  • 哨兵值必须从内存的可许值中排除。

根据您的需求进行选择。


非常感谢。我刚刚测试了 printf("%zu \n", sizeof(double *)); 并得到了 8!正如你所说的 You need to keep a track on that yourself.,我想你是指我应该知道这个缓冲区的大小是 8*4=40 字节,对吗? - Don
2
@d33j 抱歉?C11不可见吗?那不是一章,那是C标准。 :) 哦,顺便说一下,它是第6章。 - Sourav Ghosh
1
@Don 对啊,这样更安全,而且我猜对你来说也不那么麻烦,比使用哨兵值要好吧? - Sourav Ghosh
谢谢。我同意它也是安全的。 - Don

2
sizeof(buf) 是指针变量 buf 的大小,而不是它所指向的缓冲区的大小。由于硬件内存对齐要求,使用 calloc() 分配的块的大小至少为您作为参数传递给 calloc() 的值的乘积。在您的情况下,缓冲区的大小至少为 5 * sizeof(double)。据我所知,没有办法找到动态分配的内存块的大小,但只要您分配了它,就已经知道它的大小;您必须将其作为参数传递给内存分配函数(无论是 malloc()calloc()realloc() 或其他函数)。请注意保留 HTML 标签。

谢谢。讲解得很清楚 :) - Don

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接