Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在Linux中,有没有一种方法可以知道传递给_free_钩子的指针的大小?_C_Linux_Malloc_Hook_Free - Fatal编程技术网

C 在Linux中,有没有一种方法可以知道传递给_free_钩子的指针的大小?

C 在Linux中,有没有一种方法可以知道传递给_free_钩子的指针的大小?,c,linux,malloc,hook,free,C,Linux,Malloc,Hook,Free,我想跟踪一个大型应用程序当前分配了多少内存 我发现我可以在malloc/free/realloc周围安装钩子,以便拦截内存分配调用: 所以我要跟踪的是分配的总字节数-释放的总字节数 现在的问题是free只接受一个指针,而不接受一个大小 在中,我可以在mallochook中创建我自己的映射或hashmap,跟踪为该指针分配了多少内存,但这会导致相当大的开销 当调用free时(使用默认的g++malloc),有没有办法(即使有点麻烦)在Linux(64位)上获得ptr的大小 malloc_usab

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

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

所以我要跟踪的是分配的总字节数-释放的总字节数

现在的问题是free只接受一个指针,而不接受一个大小

在中,我可以在mallochook中创建我自己的映射或hashmap,跟踪为该指针分配了多少内存,但这会导致相当大的开销


当调用free时(使用默认的g++malloc),有没有办法(即使有点麻烦)在Linux(64位)上获得ptr的大小

malloc_usable_size()返回文件中可用的字节数 动态分配的缓冲区ptr,可能大于 请求的大小(但如果 请求成功)。通常,您应该存储 请求的分配大小,而不是使用此函数


这不是对您的问题的直接回答,但鉴于您对分配的总内存感兴趣,以下是解决方案:

我认为您最感兴趣的是它返回的结构的
uordblks
字段


请注意,这不是一个标准的POSIX函数,但我想这正是您对像这样的非标准自省的期望…

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


这样,您将知道当前分配的堆总和要减少多少(如果这是您的目标),并且将有一个方便的位置列出仍保留在内存中的堆的所有“区域”。

内存块的大小通常存储在指针的正下方。虽然这是一个黑客攻击(你说我可以…),但以下代码在我的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);
}
请注意,p[-2]中的大小并不完全是
492
-由于内务管理和边界对齐等原因,会占用一些额外的空间

另请注意-这与
gcc
编译器一起工作;但是
g++
抱怨指针转换,并且我没有声明
malloc\u useable\u 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 
可用的
p[-2]
之间总是有9的差异,而
p[-2]
uordblks之间总是有
1的差异。
p[-2]
方法的优点在于,它可以准确地告诉您要什么--这个指针的大小。其他的电话可能会告诉你你真正想要什么

PS对于非常大的内存块,很可能需要查看位于
*((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,然后从结果中减去(长整型*)的大小(实际上原始答案减去2*sizeof(无符号长整型),但我认为这是错误的):


链接的答案强烈建议仅在调试时使用此选项,而不要在实际代码中依赖它。我觉得有必要重复这一警告。

这在很大程度上取决于glibc的malloc du jour如何做事。。。最好用@fanl的答案。问题的可能重复部分相似,但不完全相同。那个人打算用它来计算一个数组在代码中的长度,在这些答案中建议避免使用这个数组。在这种情况下,这个问题只是为了跟踪总记忆。也许-但在这两种情况下被接受的答案是相同的。。。“使用malloc\u可用的大小()。这至少让它在我心目中成为“可能的复制品”。通过创建链接,我们为偶然发现一个问题的人提供了看到更多可能答案的机会。
printf("my pointer size is %ld\n", PSIZE(myPointer));
#define PSIZE(a) ((*((long int*)(a)-1))&~3 - sizeof(long int*))