内存块的大小通常存储在指针下方。虽然这是一个 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 的回答后,我出于好奇添加了该行。mallinfo
在看到@OliCharlesworth 的答案后,我也玩了一下输出。
您可以更改 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
和之间总是有 9 的差,usable
和p[-2]
和1
之间总是有 9 的差。该方法的优点是它可以准确地告诉您您要求的内容 -此指针的大小。其他电话实际上可能会告诉您您真正想要什么...p[-2]
uordblks
p[-2]
PS很有可能对于非常大的内存块,您需要查看long integer
位于*((long int*)(p)-1)
. 这给了我一个很好的宏的灵感:
#define PSIZE(a) (*((long int*)(a)-1))
然后你可以找出任何指针的大小
printf("my pointer size is %ld\n", PSIZE(myPointer));
无需担心指针的类型。我确认这适用于不同类型的指针,以及大于 4G 的块。显然,您可以决定在宏中减去 1,以便该数字与 mallinfo() 完全一致。
编辑:在这个较早问题的答案之一中给出了对指针下方存储内容的更完整描述。这表明我观察到的“+1”实际上是由于存储在 LSB 中的标志。正确的方法是将结果与 ~3 相加,清除两个 LSB,然后从结果中减去 (long int*) 的大小(实际上原始答案减去 2*sizeof(unsigned long int) 但我认为那是错误的):
#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*))
链接的答案强烈建议仅将其用于调试,而不是依赖于实际代码。我觉得不得不重复那个警告。