這是內存泄漏。您正在初始化myclass的一個名爲myclass_instance的靜態實例。您還正在初始化「shared_ptr myclass :: ptr」。
根據Stroustrup [3],靜態按其定義的順序進行初始化。因此,你有myclass_instance的靜態定義,它初始化構造中的內部ptr。但是,您接下來定義了靜態myclass :: ptr,它調用了shared_ptr的默認構造函數。
這是一個典型的靜態排序問題的例子。編譯器認爲myclass :: ptr並未實際初始化,因此不會破壞原始的shared_ptr。相反,它只是泄露。
您將需要某種裸指針。如果您使用的是C++ 11,那麼您可以使用三態賦值語句來執行Nifty Counter Technique,如果您確定該對象已經被初始化,則它會自動移動到自身。這很粗糙,但它的工作原理。
這是我怎麼會做它在C++ 11:
#include <crtdbg.h>
#include <memory>
using std;
#define _CRTDBG_MAP_ALLOC
#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
// Note that the count could also be a field in an initializer static used in the Nifty Counter
// Technique covered in many texts.
static int count = 0; // This gets implicitly initialized to 0 by the executable load into memory.
static struct myclass {
static shared_ptr<int> ptr;
myclass() {
if (count++ == 0) {
ptr = make_shared<int>(0); //initialization
}
}
} myclass_instance;
shared_ptr<int> myclass::ptr = count == 0 ? make_shared<int>(0) : move(myclass::ptr);
int main() {
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF |
_CRTDBG_CHECK_ALWAYS_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
return 0;
}
更多信息請參閱以下內容:
- 洛科什,J,1996年,大規模的C++軟件設計。第7.8.1.3節, 艾迪生韋斯利,馬薩諸塞州雷丁市。
- Meyers,S,2005,Effective C++,Third Edition。項目4:確保對象在使用前初始化爲 。 Addison Wesley,馬薩諸塞州雷丁市。 Stroustrup,B,2000,C++編程語言特別版。 第10.4.9節,艾迪生韋斯利,馬薩諸塞州雷丁市。
爲什麼第二次調用參數或列表中的'_CrtSetDbgFlag()'? – sharptooth 2010-06-01 09:44:36
這是將兩個語句合併爲一個的方法 – 2010-06-01 09:49:52
我不明白。你爲什麼不「或」四個標誌,而是調用「或」列表中的函數? – sharptooth 2010-06-01 10:02:42