检查指针是否指向静态分配的对象?

时间:2016-04-25 14:29:29

标签: c++ qt

我已经实现了一些QObjects的泄漏检测器。总而言之,在删除静态对象的过程中,我会检查未删除的QObject。 但问题是一些QObject是静态分配的,所以我需要从泄漏报告中删除它们。 有没有办法知道指针是否指向静态分配的对象?

1 个答案:

答案 0 :(得分:2)

AFAIK,通过简单地知道变量的地址,就没有可移植的方法来了解变量使用的持续时间类型。但如果所有动态分配都使用new,您可以使用自己的替换函数来表示operator newoperator 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 ++分配内存调用的任何可能性。

相关问题