2016-07-06 115 views
-1

我正在運行基於MFC對話框的應用程序。我有一個serial-comms線程運行在一個引用類(代碼片段之外)中,它向對話發送一個String ^(所以我可以把這些通信放在一個窗口中)。問題是(正如您從註釋代碼中看到的那樣)每當我嘗試對該字符串執行任何操作時(除了將其分配給本地變量),我都會收到「DLP_Printer_Control.exe中發生類型爲」System.AccessViolationException「的未處理異常MFC/CLI混合模式'System.AccessViolationException'

附加信息:嘗試讀取或寫入受保護的內存,這通常表示其他內存已損壞。「

在這段代碼中,它是崩潰的atoi。我使用的是atoi,因爲我有想將每個字符串元素複製到ASCII然後通過值複製到成員CString的想法。這沒有用。每條註釋行都會產生一個異常。我起訴它試圖訪問源自託管內存的內容。有任何解決方法建議?

bool CDLP_Printer_ControlDlg::UpdateCommsWindow_right(String^ strCommsLine) 
{ 
    CString strTemp = strCommsLine; 
    LPWSTR charTemp; 
    int i = 0; 
    int i_len = strTemp.GetLength(); 

    if (i_len == 0) 
     return false; 

    charTemp= strTemp.GetBuffer(i_len); 

    i =atoi((const char*)charTemp[0]); 

    strTemp.ReleaseBuffer(); 


    //if (m_strCommsLeft.IsEmpty()) 
    // return false; 

    //LPCTSTR szTemp = (LPCTSTR)strTemp; 

    //m_rightCommsLabel.SetWindowTextW((LPCTSTR)strTemp); 
    //m_rightCommsLabel.SetWindowTextW(szTemp); 
    //m_rightCommsLabel.SetWindowTextW(L"SUCCESS"); 
    return true; 
} 

回答

1

在這個片段中,它是一個崩潰的atoi。

i =atoi((const char*)charTemp[0]);

簡短的回答是,charTemp[0]TCHAR的指針,因此而const char *鑄允許它編譯,得到數據傳遞給atoi指向有效內存的指針,這會導致System.AccessViolationException異常。快速解決辦法是用i = _wtoi(charTemp);或甚至i = _ttoi(strTemp);替換該行,如下所述。

LPWSTR charTemp; /*...*/ charTemp= strTemp.GetBuffer(i_len);

如果這個項目是專爲統一這隻會編譯。這是Windows現在的常見情況,但值得注意的是,因爲您稍後會混合使用非Unicode功能,例如atoi。對於可以針對寬字符和窄字符正確編譯的變體,您可以將該聲明替換爲字符集中立的LPTSTR charTemp;

i =atoi((const char*)charTemp[0]);

這如果項目是因爲atoi內置的Unicode需要一個普通的老const char *作爲參數,只會編譯。字符集中立的MS映射是_ttoi,所以在投下錯誤的[0]const char *後,代碼將變爲簡單i = _ttoi(charTemp);

最後,CString有一個內置的LPCTSTR運營商,所以沒有必要GetBuffer/ReleaseBuffer和使用一箇中間LPTSTR charTemp;。以下將一步完成相同的工作。

i = _ttoi(strTemp); 
+0

非常感謝。_ttoi()停止了這個錯誤,但這竟然是一隻紅鯡魚。其實,如果我有一個成員int,然後將我設置爲此成員int,我得到「異常拋出:'System.NullReferenceException'」我做它的時刻;( –

+0

'如果我有一個成員int [...] '如果你通過一個NULL對象指針調用成員函數,會發生這種情況,但是如果沒有MCVE就不可能猜測出來。 – dxiv