0

我正在尝试使用 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自己的析构函数内的计数器:()。

问题再次是:真正会发生什么?我怎样才能避免这个问题?通过编译器标志强制不内联也不行。(我不希望它不被内联,因为它可能会损害性能)。

4

1 回答 1

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 的大小。

于 2013-08-14T12:23:36.950 回答