2013-10-11 229 views
0

使用以下C++代碼時,我在運行時遇到了未處理的異常錯誤,您可以使用Visual Studio進行調試並遵循錯誤。爲什麼會發生這種異常,你能解釋一下嗎?msvcr100d.dll未處理的異常

首先,我定義一個類與會員專區變量「_name」

void insert_Fenster(int pos,wstring name); 
wstring get_Fenster_name(int pos); 

class Fenster 
{ 
public: 
    Fenster(wstring name) 
     :_name(name) 
    {} 

    void reload() 
    { 
     _name; 
     insert_Fenster(1,L"temp"); 
     wstring tmp = get_Fenster_name(1); 
     _name = tmp; //ERROR!!! 
    } 

    wstring get_name() 
    { 
     return _name; 
    } 

private: 
    wstring _name; 
}; 

其次,我定義一個類來保存地圖一類

class FensterManager 
{ 
public: 
    bool has(int pos) 
    { 
     if (_mapFenster.find(pos)!=_mapFenster.end()) 
      return true; 
     else 
      return false; 
    } 

    void insert(int pos,wstring name) 
    { 
     if (has(pos)) 
     { 
      _mapFenster.erase(pos); 
     } 
     _mapFenster.insert(make_pair(pos,Fenster(name))); 
    } 

    Fenster& get_Fenster(int pos) 
    { 
     return _mapFenster.at(pos); 
    } 

private: 
    static map<int,Fenster> _mapFenster; 
}; 

有些UTIL功能

void insert_Fenster(int pos,wstring name) 
{ 
    FensterManager fm; 
    fm.insert(pos,name); 
} 

void reload_Fenster(int pos) 
{ 
    FensterManager fm; 
    if (fm.has(pos)) 
     fm.get_Fenster(pos).reload(); 
} 

wstring get_Fenster_name(int pos) 
{ 
    wstring name; 

    FensterManager fm; 
    if (fm.has(pos)) 
     name = fm.get_Fenster(pos).get_name(); 

    return name; 
} 

//Init of static member before main function 
map<int,Fenster> FensterManager::_mapFenster; 

即主要功能

void main() 
{ 
    insert_Fenster(1,L"xyz"); 
    reload_Fenster(1); 
} 

異常發生在「Fenster」類的「重新加載」功能中。

錯誤消息: Regular_Expression.exe中的0x005cca34(msvcr100d.dll)未處理的異常:0xC0000005:訪問衝突寫入位置0xfeeefeee。

+1

請發出原始代碼郵件 – billz

+1

Regular_Expression.exe中的0x005cca34(msvcr100d.dll)未處理的異常:0xC0000005:訪問衝突寫入位置0xfeeefeee。 – rich

+0

順便說一句爲什麼代碼有註釋'//錯誤!!!'是那種一廂情願的想法還是另一個錯誤?還是同樣的錯誤?還是毫無意義的評論? – doctorlove

回答

3

當你調用reload_Fenster(1);,它會調用Fenster::reload

void main() 
{ 
    FensterManager fm; 
    insert_Fenster(fm, 1,L"xyz"); 
    reload_Fenster(fm, 1); 
} 

插入和重載方法應該如下更新。在該功能中,您可以撥打insert_Fenster(1,L"temp");FensterManager::insert將首先從地圖上清除位置1。所以當你回到Fenster::reload時,實例已被刪除。只要嘗試訪問_name,就嘗試訪問已刪除的內存。

編輯: 澄清;這個函數調用:

fm.get_Fenster(pos).reload(); 

會先調用fm.get_Fenster(pos),然後調用reload()的結果。如果fm.get_Fenster(pos)reload()函數中發生更改,則執行不會移動新的Fenster,但舊的將繼續執行。即使你刪除舊的Fenster。

如果你仍然在裏面運行函數,你應該確保不要刪除一個實例。當您嘗試訪問成員時,它會使應用程序崩潰,因爲它們存儲在已刪除的內存中。

+0

這個答案似乎是現貨。 –

+0

但在擦除之後,它也將位置1插入地圖'_mapFenster.insert(make_pair(pos,Fenster(name)));' – rich

+0

@rich yes,但是您在那裏創建了一個新的Fenster。 'Fenster :: reload'仍在執行舊的實例。 '* this'在'Fenster :: reload'函數中不會改變。 – wimh

0

看起來像裏面的東西void insert_Fenster(int pos,wstring name); - 進一步查看調用堆棧,您會看到代碼的哪一部分調用到運行時DLL中。這將是錯誤。

+0

爲什麼會是'insert_Fenster'? – billz

0

你能提供關於未處理異常的更多信息嗎?

在上面的代碼中有一個明顯的錯誤。 insert_Fenster插入到FensterManager實例中,reload_Fenster嘗試從FensterManager的另一個實例中重新加載,這是錯誤的。

void insert_Fenster(FensterManager &fm, int pos,wstring name) 
{ 
    fm.insert(pos,name); 
} 

void reload_Fenster(FensterManager &fm, int pos) 
{ 
    if (fm.has(pos)) 
     fm.get_Fenster(pos).reload(); 
} 
+1

是的,但是,由於一些瘋狂的原因,數據是靜態的:'靜態地圖 _mapFenster;'當然,你的方式更好,但我不認爲這是問題。我也不相信代碼發佈編譯。 – doctorlove

+1

是的,這是不同的實例,但它們都擁有相同的靜態成員 – rich

+0

@rich您會意識到這是一個非常令人困惑的事情,可能要考慮重新設計 – doctorlove