2017-06-12 87 views
4

我想知道使用callocbyte中分配的缓冲区的大小。通过测试在我的机器如下:确定在堆中分配的缓冲区的大小

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

结果是8,甚至当我改变只有一个元素我仍然得到8.我的问题是:

  1. 这是否意味着我只能乘8 * 5以字节为单位获取缓冲区大小? (我以为sizeof将返回40)。
  2. 如何才能使字节中返回缓冲区大小的宏(要检查的缓冲区可能是char,int,doublefloat)?

任何想法表示赞赏。

+0

释放calloc()调用malloc(),malloc.c是代码超过5322线,所以它不是微不足道的,但是(没有研究)我认为在缓冲区开始之前有一个计数值,这对我来说很有意义,因为free()不知道calloc使用的参数() – Marichyasana

+0

@Marichyasana您的评论isn' t关于[tag:c],它关于* some *(假设的)实现。实现可以自由选择如何存储'free()'工作所需的信息。事实上,只是一个指向下一个块的指针可能更容易做到,当然,你可以实现你自己的替代'malloc()',它也提供了一些'sizeOfChunk()'函数,但是成为该语言的扩展*。而且,顺便说一句,分配块的程序*知道它的大小(它将它传递给分配函数)。 –

回答

6

引用C11,章§6.5.3.4,(重点煤矿

sizeof操作者产生其操作数的大小(以字节为单位),其可以是 表达或括号名称一种。 大小由操作数的类型 决定。 [...]

因此,使用sizeof无法获得指针指向的内存位置的大小。你需要保持自己的轨道。

详细说明,您的案例相当于sizeof (double *),它基本上根据您的环境给出指针的大小(加倍)。

没有通用或直接的方式从内存分配器函数中获取分配内存的大小。但是,您可以使用sentinel value标记分配的缓冲区的结束和使用循环,可以检查该值,但这意味着

  • 一个额外的元素的分配来保存标记值本身
  • 标记值必须从存储器中的允许值中排除。

根据您的需要选择。

+0

...引用第11章什么? K&R? – d33j

+0

非常感谢。我刚刚测试了'printf(“%zu \ n”,sizeof(double *));'并得到了'8!正如你所说'你需要自己保持一个轨迹。',我想你的意思是我应该知道这个缓冲区的大小是8 * 4 = 40字节,这是正确的吗? – Don

+2

@ d33j对不起? “C11”不可见?这不是一章,这是C标准。 :)哦,这是第6章,顺便说一句。 –

2

sizeof(buf)buf变量的大小,它是一个指针,而不是它指向的缓冲区的大小。

由于内存对齐要求(由硬件强加),分配calloc()的块的大小至少是您传递给calloc()作为参数的值的乘积。
就你而言,缓冲区的大小至少为5 * sizeof(double)

Afaik没有办法找到一个动态分配的内存块的大小,但只要你分配它,你已经知道它的大小;你必须把它作为参数传递给内存分配函数(无论是malloc()calloc()realloc()或任何其他。

+0

谢谢。很好解释:) – Don