C ++:如何在运行时计算所有实例化对象?

时间:2010-04-28 12:37:46

标签: c++ debugging runtime tracing

我有一个由许多C ++类组成的大型框架。有没有办法在运行时使用任何工具来跟踪正在构建和当前存在的所有C ++对象?

例如,在特定时间t1,应用程序可能有对象A1,A2和B3,但在时间t2,它有A1,A4,C2等等?

这是一个跨平台框架,但我熟悉在Linux,Solaris和(可能)Mac OS X中工作。

5 个答案:

答案 0 :(得分:10)

您可以在要计算的对象的析构函数和构造函数中注入代码:

SomeObject::SomeObject() {
   ++globalSomeObjectCounter;
}

SomeObject::~SomeObject() {
   --globalSomeObjectCounter;
}

不要忘记在所有构造函数(复制构造函数等)中增加计数器。

编辑:在这种情况下,可以使用奇怪的重复模板模式:

template <typename T>
struct Counter
{
    Counter() {++counter;}
    virtual ~Counter() {--counter;}
    static int counter;
};
template <typename T> int Counter<T>::counter(0);

然后:

class SomeObject : public Counter<SomeObject> {
}

为每个类类型自动生成一个计数器。

答案 1 :(得分:1)

我假设您只计算堆上的对象。如果是这种情况,您可以将所有调用记录为new并删除,方法是将其替换为一些自定义宏。

我们开发了这样的自定义日志记录工具。主要目的是跟踪内存泄漏,但它也可用于在任何特定时间找出有多少对象。例如,

#define MY_NEW_OBJECT(a, T) \
    a = new T;              \
    MY_LOGGING((LM_DEBUG, "[NEW OBJ ] 0x%08X(%s), %4d bytes. %-20s - %-40s - %4d\n", a, #T,  \
    sizeof(T), __FILE__, __func__, __LINE__));

MyClass* myObj;
MY_NEW_OBJECT(myObj, MyClass);

MY_LOGGING会在每行的开头自动添加时间戳。该行包含类名,文件名,行号,函数名和大小。

实用程序解析日志记录文件并生成显示对象数量,使用的总大小等的图表。

当然,您必须用宏替换每个新的/删除调用。这可能是相当多的工作。

答案 2 :(得分:0)

我自己没有使用它Massif可能是你正在寻找的工具。 http://valgrind.org/info/tools.html

答案 3 :(得分:0)

创建一个与Java的Object等效的特殊基类,并使每个类都从中派生出来。然后在该类中,全局计数器操作Andreas Brinck分别在构造函数/析构函数中建议。除了确保派生对象仅被计为一个对象外,它还意味着您只需要构造1个构造函数和1个析构函数。虽然当然缺点是你需要稍微改变每个班级的定义......

答案 4 :(得分:0)

这只是Solaris,但如果这是一个选项,您可以使用dtrace跟踪每个类的构造函数和析构函数调用的数量,并以一定间隔打印出来。这将需要大量工作来设置所有进入/返回块,但我怀疑dtrace脚本可以自动生成。