有没有办法知道在Linux中传递给__free_hook的指针的大小?

我想跟踪一个大型应用程序当前分配了多less内存。

我发现我可以在malloc / free / realloc周围安装钩子以拦截内存分配调用:

http://man7.org/linux/man-pages/man3/malloc_hook.3.html

所以我想跟踪的是总字节数分配 – 总字节数释放。

现在问题是免费只需要一个指针,而不是一个大小。

在我的malloc挂钩中可以创build自己的映射或hashmap,跟踪为该指针分配了多less内存,但这会导致相当多的开销。

有没有什么办法(即使这是一个黑客)获得Linux(64位)的大小的空闲时,免费调用(使用默认的g ++ malloc)?

linux man malloc_usable_size

malloc_usable_size()返回动态分配的缓冲区ptr中可用的字节数,该字节数可能大于所请求的大小(但如果请求成功,则保证其大小至少一样大)。 通常,您应该存储所请求的分配大小,而不是使用此功能。

这不是对你的问题的直接回答,而是看到你对分配的内存感兴趣,那么这里就是解决方案:

  • mallinfo()

我想你会对它返回的结构的uordblks字段感兴趣。

请注意,这不是一个标准的POSIX函数,但我想这就是你所期望的非标准内省这样的…

内存块的大小通常存储在指针的下方。 虽然这是一个黑客(你说我可以…),下面的代码运行在我的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的回答之后,我也玩了一下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 

usablep[-2]之间总是有9的差异, p[-2]uordblks之间有1差异。 p[-2]方法的优点是,它告诉你所要求的是什么 – 这个指针的大小。 其他电话可能实际上告诉你你真正想要什么…

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()完全一致。

编辑:一个更完整的描述存储在指针下面的东西在这个早期的问题的答案之一。 这表明我观察到的“+1”实际上是由于存储在LSB中的标志。 正确的做法是用〜3结果,清除两个LSB,然后从结果中减去(long int *)的大小(实际上原来的答案减去2 * sizeof(unsigned long int),但我认为这是错误):

 #define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*)) 

链接的答案强烈建议只用于调试,而不是依赖于它的实际代码。 我感到不得不重复这个警告。

您需要在malloc中安装一个钩子来构建一个缓存所请求块的大小的指针表,然后当您释放时,搜索malloc'd项的以前的数据库中的指针。

这样你就可以知道当前分配的堆的总和是多少(如果这是你的目标),并且将有一个方便的地方来列出所有仍然保存在内存中的堆的“区域”。