我正在尝试使用易失性静态变量编写一个非常简单的内存大小计数器来跟踪某个类中的分配。
我编写了类'析构函数来原子地减少这个静态的volatile整数,但是编译器(VC VS2010)将它优化掉了(内联它,虽然它不应该 - 析构函数中的变量是易变的,也许它应该采取考虑到..?)。相反,析构函数似乎从不被调用(即类的成员被正确处理掉,但显然没有使用自定义析构函数)。
我无法编写代码片段(它来自“分类”源代码)。但是,基本上,它看起来都像这样:
标题:
class CSomething
{
CObject m_object;
...
public:
static volatile int ms_counter;
~CSomething();
}
.cpp:
CSomething::CSomething()
{
DoStuffWith(m_object);
AtomicAdd(ms_counter, m_object.GetTotalSize());
}
CSomething::~CSomething()
{
AtomicDecrement(ms_counter, m_object.GetTotalSize());
}
要恢复:~CSomething()
析构函数内联或优化(?),因为我无法在其中放置断点。 ms_counter
的值仅增加,但从不减少(尽管m_object
的析构函数明确地被调用)。 (不,我不能减少m_object
自己的析构函数内部的计数器:()。
问题是:真的会发生什么?我该如何避免这个问题?通过编译器标志强制没有内联也不会这样做..(我不希望它不被内联,因为它可能会损害性能)。
答案 0 :(得分:0)
这里的问题是,当你到达CSomething的析构函数体时,m_object已经被破坏。(编辑因为它是完全错误的)考虑以下代码:
#include <iostream>
using std::cout;
using std::endl;
class A
{
public:
A(){cout << "A()" << endl;}
~A(){cout << "~A()" << endl;}
};
class B
{
A a;
public:
B(){cout << "B()" << endl;}
~B(){cout << "~B()" << endl;}
};
int main(void)
{
B b;
return 0;
}
编译并运行:
$ g++ test.cc -o test && ./test
A()
B()
~B()
~A()
因此,在调用析构函数之前,您必须跟踪并保存m_object的大小。