内存块的大小通常存储在指针下方。虽然这是一个 hack(你说我可以......),但以下代码在我的 Linux 机器上运行:
#include <stdio.h>
#include <stdlib.h>
int main(){
int *p, n=123;
p = (int*)malloc(n*sizeof(int));
printf("allocated %d bytes for p\n", n*sizeof(int));
printf("p[-2] : %d \n", *(p-2));
printf("malloc_useable_size(p) : %d\n", malloc_usable_size(p));
free(p);
}
它产生的输出是这样的:
allocated 492 bytes to p
p[-2] : 513
malloc_useable_size(p): 504
请注意,p[-2] 中的大小不完全是 492 - 由于内务管理和边界对齐等原因,会占用一些额外的空间。
另请注意 - 这适用于 gcc 编译器;但是g++ 抱怨指针转换,并且我没有声明malloc_useable_size()。看到@fanl 的回答后,我出于好奇添加了该行。在看到@OliCharlesworth 的回答后,我也对mallinfo 的输出进行了一些尝试。
你可以改变 n 的值,你会发现事情非常吻合——例如,如果你将 n(在我上面的代码中)从 100 步进到 119,不同感兴趣变量的值如下:
n | p[-2] | usable | uordblks
----+-------+--------+---------
100 417 408 416
101 417 408 416
102 417 408 416
103 433 424 432
104 433 424 432
105 433 424 432
106 433 424 432
107 449 440 448
108 449 440 448
109 449 440 448
110 449 440 448
111 465 456 464
112 465 456 464
113 465 456 464
114 465 456 464
115 481 472 480
116 481 472 480
117 481 472 480
118 481 472 480
119 497 488 496
usable 和 p[-2] 之间始终存在 9 的差异,p[-2] 和 uordblks 之间始终存在 1 的差异。 p[-2] 方法的优势在于它可以准确地告诉您要求 的内容——this 指针的大小。其他电话实际上可能会告诉您您真正想要什么...
PS 很有可能对于非常大的内存块,您需要查看位于*((long int*)(p)-1) 的long integer。这给了我一个很好的宏的灵感:
#define PSIZE(a) (*((long int*)(a)-1))
然后你可以找出任何指针的大小
printf("my pointer size is %ld\n", PSIZE(myPointer));
无需担心指针的类型。我确认这适用于不同类型的指针,以及大于 4G 的块。显然,您可以决定在宏中减去 1,以便该数字与 mallinfo() 完全一致。
编辑:在this earlier question 的答案之一中给出了对指针下方存储内容的更完整描述。这表明我观察到的“+1”实际上是由于存储在 LSB 中的标志。正确的方法是将结果与 ~3 相加,清除两个 LSB,然后从结果中减去 (long int*) 的大小(实际上原始答案减去 2*sizeof(unsigned long int) 但我认为那是错误):
#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*))
链接的答案强烈建议仅将其用于调试,而不是依赖于实际代码。我觉得不得不重复那个警告。