2016-07-06 12 views
-1

Ich führe eine MFC-Dialog-basierte Anwendung. Ich habe einen seriell-comms-Thread, der in einer Referenzklasse läuft (außerhalb des Code-Snippets), der einen String^an den Dialog sendet (damit ich die comms in ein Fenster setzen kann). Das Problem ist (wie Sie aus kommentiertem Code sehen), dass jedes Mal, wenn ich versuche, irgendetwas mit dieser Zeichenkette zu tun (außer einer lokalen Variablen zuzuweisen), bekomme ich "Eine nicht behandelte Ausnahme des Typs 'System.AccessViolationException' in DLP_Printer_Control.exeMFC/CLI gemischten Modus 'System.AccessViolationException'

Zusätzliche Informationen: Es wurde versucht, geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass anderer Speicher beschädigt ist. "

In diesem Snippet stürzt das Atoi ab. Ich verwende atoi, weil ich die Idee hatte, jedes Zeichenfolgenelement in ASCII zu kopieren und dann nach Wert in einen Mitglieds-CString zu kopieren. Das hat nicht funktioniert. Jede kommentierte Zeile erzeugt eine Ausnahme. Ich versuche es mit dem Versuch, auf etwas zuzugreifen, das in gemanagtem Gedächtnis entstanden ist. Wurden Workarounds vorgeschlagen?

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; 
} 

Antwort

1

In diesem Snippet ist es die atoi, die abstürzt.

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

Kurze Antwort ist, dass charTemp[0] ist ein TCHAR und nicht ein Zeiger, so dass während der const char * Guss kompilieren können, der Wert, der atoi geben wird ist nicht ein Zeiger auf gültigen Speicher, der die Ausnahme System.AccessViolationException verursacht. Die schnelle Lösung wäre, diese Zeile durch i = _wtoi(charTemp); oder sogar i = _ttoi(strTemp); wie unten beschrieben zu ersetzen.

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

Dies wird nur kompiliert, wenn das Projekt für Unicode gebaut wird. Das ist der übliche Fall in Windows heutzutage, aber es ist erwähnenswert, da Sie später Nicht-Unicode-Funktionen wie atoi einmischen. Für eine Variante, die sowohl für breite als auch für schmale Zeichensätze korrekt kompiliert werden würde, könnten Sie die Deklaration durch die charset-neutrale LPTSTR charTemp; ersetzen.

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

kompilieren Dies wird nur, wenn das Projekt nicht für Unicode seit atoi erwartet eine einfache alte const char * als Argument aufgebaut ist. Das Zeichensatz-neutrale MS-Mapping ist _ttoi, also würde nach dem Fallenlassen des falschen [0] und const char * Cast der Code einfach i = _ttoi(charTemp); werden.

Schließlich hat CString einen eingebauten in LPCTSTR Betreiber, so dass es keine Notwendigkeit, GetBuffer/ReleaseBuffer ist und einen Zwischen LPTSTR charTemp; verwenden. Das Folgende wird die gleiche Aufgabe in einem Schritt erledigen.

i = _ttoi(strTemp); 
+0

Vielen Dank.Der _ttoi() stoppte diesen Fehler, aber es stellte sich heraus, dass es ein Ablenkungsmanöver war. Eigentlich, wenn ich ein Mitglied int habe, dann setze ich I auf dieses Mitglied int, bekomme ich "Exception geworfen: 'System.NullReferenceException'" in dem Moment, wenn ich es mache; ( –

+0

'wenn ich ein Mitglied Int haben [...] 'Das würde passieren, wenn Sie die Member-Funktion über einen NULL-Objektzeiger aufrufen würden, aber es ist unmöglich, ohne MCVE zu raten. – dxiv