[英]c++ std::unordered_map singleton access violation error
template <typename T> class singleton
{
public:
static T* ms_singleton;
singleton()
{
assert(!ms_singleton);
long offset = (long)(T*)1 - (long)(singleton <T>*) (T*) 1;
ms_singleton = (T*)((long)this + offset);
}
virtual ~singleton()
{
assert(ms_singleton);
ms_singleton = 0;
}
static T& Instance()
{
assert(ms_singleton);
return (*ms_singleton);
}
static T* instance_ptr()
{
return (ms_singleton);
}
};
class Test
{
private:
DWORD X;
}
typedef Test* LPTEST;
class TestManager : public singleton<TestManager>
{
public:
TestManager();
virtual ~TestManager();
LPTEST CreateTest(DWORD id);
protected:
private:
std::unordered_map<DWORD, LPTEST> test_map;
};
LPTEST TestManager::CreateTest(DWORD id)
{
LPTEST test = new Test;
if (id)
{
test_map.insert(std::make_pair(id, test));
}
return (test);
}
我創建了一個類似的代碼。
當我運行以下 function 時。
LPTEST 測試 = TestManager::Instance().CreateTest(61);
但“test_map.insert”給出了訪問沖突錯誤。
test_map.insert -> 如果我關閉 function 它工作正常。
所有代碼都正常。 為什么我對 std:map 之類的代碼有這樣的問題。
如果你能幫忙,我會很高興。
通過如下更改 Singleton 代碼。 我解決了這個問題。
template <typename T> class singleton
{
public:
singleton() {}
~singleton() {}
static T& Instance()
{
static T instance;
return instance;
}
singleton(const singleton&) = delete;
singleton& operator=(const singleton&) = delete;
};
@drescherjm,@UnholySheep 感謝您的幫助。
是不是覺得這段代碼中有一段代碼會在以后造成麻煩? 這段代碼可以更好嗎? 如何?
您的代碼太復雜、危險並且充滿了未定義的行為。
以下是一些問題:
offset
計算完全沒有意義!static_cast
, dynamic_cast
完全理解為什么使用這種轉換。在實踐中,使用 Meyer 的 singleton,您很少需要定義這樣的模板。
這樣的事情要簡單得多:
using TestMap = std::unordered_map<DWORD, Test>;
class TestManager
{
public:
static TestMap &GetTestMap();
Test *CreateTest(DWORD id);
};
// testmanager.cpp
TestMap &TestManager::GetTestMap()
{
// Creation of the object is thread safe but if you want
// to use it from multiple threads, you have to provide
// your own synchronisation like mutex.
static TestMap testMap;
return testMap;
}
Test *TestManager::CreateTest(DWORD id)
{
// allocate a pair and return a reference to value
// if key already exist, return a reference to existing value.
auto &mapValue = GetTestMap()[id];
// as unique_ptr are stored in the map,
// memory managment can be simplified
// could also use make_unique here
mapValue.reset(new Test);
// return a raw pointer as in your original code
return mapValue.get();
}
根據需要和您對 C++ 的理解程度,該代碼可以改進...正如所寫,一旦您了解一些基本的 C++ 11,就很容易理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.