我已经实现了一些QObjects的泄漏检测器。总而言之,在删除静态对象的过程中,我会检查未删除的QObject。 但问题是一些QObject是静态分配的,所以我需要从泄漏报告中删除它们。 有没有办法知道指针是否指向静态分配的对象?
答案 0 :(得分:2)
AFAIK,通过简单地知道变量的地址,就没有可移植的方法来了解变量使用的持续时间类型。但如果所有动态分配都使用new
,您可以使用自己的替换函数来表示operator new
和operator delete
的不同签名,并使用它们来管理地图或一组所有分配。参考当前C ++标准草案n4296:
17.6.4.6替换函数[replacement.functions]
...
C ++程序可以为12个动态内存分配函数签名中的任何一个提供定义 在标题< new>中声明(3.7.4,18.6):
- operator new(std :: size_t)
- operator new(std :: size_t,const std :: nothrow_t&)
- operator new
- operator new [](std :: size_t,const std :: nothrow_t&)
- operator delete(void *)
- operator delete(void *,const std :: nothrow_t&)
- operator delete
- operator delete [](void *,const std :: nothrow_t&)
- operator delete(void *,std :: size_t)
- operator delete(void *,std :: size_t,const std :: nothrow_t&)
- operator delete [](void *,std :: size_t)
- operator delete [](void *,std :: size_t,const std :: nothrow_t&)
使用程序的定义而不是实现提供的默认版本(18.6)。 这种替换发生在程序启动之前(3.2,3.6)。该计划的声明不得 指定为内联。无需诊断。
这将允许您构建一种手工制作的 valgrind并存储在例如数组中 - 在operator new中使用标准容器可能很繁琐,因为它们确实使用了operator new! - 已分配块的列表。在一个简单的层面上,这样的东西可能有所帮助:
// use a SZ value big enough for your program...
#define SZ 1000
struct Alloc {
void *p;
size_t size;
} alloc[SZ];
bool inited = false;
void * operator new(size_t s) {
void * p = malloc(s);
if (p != NULL) {
// fprintf(stderr, "Allocate %d at %p\n", s, p); // for debug
for (int i=0; i<SZ; i++) {
if (alloc[i].p == NULL) {
alloc[i].p = p;
alloc[i].size = s;
break;
}
}
}
return p;
}
void operator delete(void *p) {
size_t s = 0;
if (p != NULL) {
for (int i=0; i<SZ; i++) {
if (alloc[i].p == p) {
s = alloc[i].size;
alloc[i].p = NULL;
break;
}
}
free(p);
}
// fprintf(stderr,"De-allocate %p (%d)\n", p, s); // for debug
}
请注意,我故意使用C stdio函数来调试跟踪,以避免C ++标准库io中C ++分配内存调用的任何可能性。