【问题标题】:Check if a pointer points to statically allocated object?检查指针是否指向静态分配的对象?
【发布时间】:2016-08-19 00:25:29
【问题描述】:

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

【问题讨论】:

  • 这个泄漏报告是什么?有很多实用程序已经这样做了,所以我想知道你是否在重新发明轮子。
  • 这个问题与:stackoverflow.com/q/3065092/694576 相关,如果不是后者的重复。

标签: c++ qt


【解决方案1】:

AFAIK,没有可移植的方法通过简单地知道变量的地址来知道变量使用的持续时间类型。但是,如果您的所有动态分配都使用 new,您可以使用自己的 替换函数 来处理 operator newoperator delete 的不同签名,并使用它们来管理一个映射或一组所有分配.当前 C++ 标准草案 n4296 中的参考:

17.6.4.6 替换函数 [replacement.functions]

...
C++ 程序可以为十二个动态内存分配函数签名中的任何一个提供定义 在标头 (3.7.4, 18.6) 中声明:

  • 新的运算符(std::size_t)
  • 新运算符(std::size_t, const std::nothrow_t&)
  • 新运营商
  • 运算符 new[](std::size_t, const std::nothrow_t&)
  • 运算符删除(void*)
  • 操作符删除(void*, const std::nothrow_t&)
  • 运算符删除
  • 运算符 delete[](void*, const std::nothrow_t&)
  • 运算符删除(void*, std::size_t)
  • 操作符删除(void*, std::size_t, const std::nothrow_t&)
  • 运算符删除[](void*, std::size_t)
  • 运算符 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++ 分配内存的任何可能性。

【讨论】:

    猜你喜欢
    • 2011-03-05
    • 1970-01-01
    • 2022-01-14
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 2011-06-07
    相关资源
    最近更新 更多