2016-04-16 4 views
-1

Ich bekomme weiter die Nachricht Error reading characters of stringUnable to read memory. Ich bin nicht sicher, wie man es korrigiert, da es scheint, dass alles in Ordnung ist, wenn die CString.Format() - Funktion aufgerufen wird. HierCString Format() kann Speicher nicht lesen VS2015

ist der Punkt in strnlen.cpp wo der Fehler auftritt: enter image description here

Und hier sind die Einheimischen zum Zeitpunkt der Pause: enter image description here

Dies ist die Funktion, die strnlen aufruft. cpp (die letzte Zeile ist die Stelle, an der die Unterbrechung auftritt):

char comp[50]; 
gethostname(comp,50); 

CString textmsg; 
textmsg.Format("%s %s: %s",TEXT,comp, m_edit_message); 

m_edit_message ist eine CString-Variable.

Schließlich ist hier der Call-Stack zum Zeitpunkt des Fehlers:

NetChess.exe!common_strnlen_c<unsigned char>(const unsigned char * const string, const unsigned int maximum_count) Line 36 C++ 
NetChess.exe!common_strnlen_simd<0,unsigned char>(const unsigned char * const string, const unsigned int maximum_count) Line 94 C++ 
NetChess.exe!common_strnlen<unsigned char>(const unsigned char * const string, const unsigned int maximum_count) Line 153 C++ 
NetChess.exe!strnlen(const char * string, unsigned int maximum_count) Line 165 C++ 
NetChess.exe!__crt_stdio_output::output_processor<char,__crt_stdio_output::string_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::string_output_adapter<char> > >::type_case_s_compute_narrow_string_length(const int maximum_length, char __formal) Line 2268 C++ 
NetChess.exe!__crt_stdio_output::output_processor<char,__crt_stdio_output::string_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::string_output_adapter<char> > >::type_case_s() Line 2255 C++ 
NetChess.exe!__crt_stdio_output::output_processor<char,__crt_stdio_output::string_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::string_output_adapter<char> > >::state_case_type() Line 1999 C++ 
NetChess.exe!__crt_stdio_output::output_processor<char,__crt_stdio_output::string_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::string_output_adapter<char> > >::process() Line 1644 C++ 
NetChess.exe!common_vsprintf<__crt_stdio_output::standard_base,char>(const unsigned __int64 options, char * const buffer, const unsigned int buffer_count, const char * const format, __crt_locale_pointers * const locale, char * const arglist) Line 163 C++ 
NetChess.exe!__stdio_common_vsprintf(unsigned __int64 options, char * buffer, unsigned int buffer_count, const char * format, __crt_locale_pointers * locale, char * arglist) Line 235 C++ 
NetChess.exe!_vscprintf_l(const char * const _Format, __crt_locale_pointers * const _Locale, char * _ArgList) Line 1655 C++ 
NetChess.exe!_vscprintf(const char * const _Format, char * _ArgList) Line 1672 C++ 
[External Code] 
NetChess.exe!CMessageSend::OnOK() Line 60 C++ 
NetChess.exe!_AfxDispatchCmdMsg(CCmdTarget * pTarget, unsigned int nID, int nCode, void(CCmdTarget::*)() pfn, void * pExtra, unsigned int nSig, AFX_CMDHANDLERINFO * pHandlerInfo) Line 77 C++ 
NetChess.exe!CCmdTarget::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo) Line 372 C++ 
NetChess.exe!CDialog::OnCmdMsg(unsigned int nID, int nCode, void * pExtra, AFX_CMDHANDLERINFO * pHandlerInfo) Line 85 C++ 
NetChess.exe!CWnd::OnCommand(unsigned int wParam, long lParam) Line 2779 C++ 
NetChess.exe!CWnd::OnWndMsg(unsigned int message, unsigned int wParam, long lParam, long * pResult) Line 2092 C++ 
NetChess.exe!CWnd::WindowProc(unsigned int message, unsigned int wParam, long lParam) Line 2078 C++ 
NetChess.exe!AfxCallWndProc(CWnd * pWnd, HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 265 C++ 
NetChess.exe!AfxWndProc(HWND__ * hWnd, unsigned int nMsg, unsigned int wParam, long lParam) Line 418 C++ 
[External Code] 
NetChess.exe!CWnd::IsDialogMessageA(tagMSG * lpMsg) Line 193 C++ 
NetChess.exe!CWnd::PreTranslateInput(tagMSG * lpMsg) Line 4586 C++ 
NetChess.exe!CDialog::PreTranslateMessage(tagMSG * pMsg) Line 80 C++ 
NetChess.exe!CWnd::WalkPreTranslateTree(HWND__ * hWndStop, tagMSG * pMsg) Line 3358 C++ 
NetChess.exe!AfxInternalPreTranslateMessage(tagMSG * pMsg) Line 233 C++ 
NetChess.exe!CWinThread::PreTranslateMessage(tagMSG * pMsg) Line 777 C++ 
NetChess.exe!AfxPreTranslateMessage(tagMSG * pMsg) Line 252 C++ 
NetChess.exe!AfxInternalPumpMessage() Line 178 C++ 
NetChess.exe!CWinThread::PumpMessage() Line 900 C++ 
NetChess.exe!CWinThread::Run() Line 629 C++ 
NetChess.exe!CWinApp::Run() Line 787 C++ 
NetChess.exe!AfxWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 47 C++ 
NetChess.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 26 C++ 
[External Code] 

MessageSend.cpp

// MessageSend.cpp : implementation file 
// 

#include "stdafx.h" 
#include "NetChess.h" 
#include "MessageSend.h" 
#include "NetChessDoc.h" 
#include "NetChessView.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 

//////////////////////////////////////////////////// CMessageSend dialog 

bool BoundsCheck2(char *myTestArray, unsigned int expectedSize); 

CMessageSend::CMessageSend(CWnd* pParent) 
    : CDialog(CMessageSend::IDD, pParent) 
{ 
    //{{AFX_DATA_INIT(CMessageSend) 
    m_edit_message = _T(""); 
    m_edit_receive_message = _T(""); 
    //}}AFX_DATA_INIT 
} 
void CMessageSend::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialog::DoDataExchange(pDX); 
    //{{AFX_DATA_MAP(CMessageSend) 
    DDX_Text(pDX, IDC_EDIT_MESSAGE, m_edit_message); 
    DDV_MaxChars(pDX, m_edit_message, 50000); 
    DDX_Text(pDX, IDC_EDIT_RECEIVE_MESSAGE, m_edit_receive_message); 
    //}}AFX_DATA_MAP 
} 
BEGIN_MESSAGE_MAP(CMessageSend, CDialog) 
    //{{AFX_MSG_MAP(CMessageSend) 
    ON_WM_VSCROLL() 
    //}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
//////////////////////////////////////CMessageSend message handlers 
void CMessageSend::OnOK() 
{ 
    //msgDlg.m_edit_send_message 
    UpdateData(TRUE); 
    char comp[50]; 
    if (BoundsCheck2(comp, 50)) 
     gethostname(comp,50); 

    CString textmsg; 
    textmsg.Format("%s %s: %s",TEXT,comp, (CString) m_edit_message); 

    m_edit_receive_message += (CString)comp + ": " + m_edit_message + (CString)"\r\n";; 
    ((CNetChessView*)((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView())->SendSockData((unsigned char*)textmsg.GetBuffer(0),textmsg.GetLength()); 
    //textmsg.ReleaseBuffer(0); 
    m_edit_message = ""; 
    UpdateData(FALSE); 
    CWnd* wnd= GetDlgItem(IDC_EDIT_RECEIVE_MESSAGE); 
    wnd->PostMessage(WM_VSCROLL,SB_BOTTOM,0); 
    //CDialog::OnOK(); 
} 
void CMessageSend::SetReceiveData(char* data) 
{ 
    m_edit_receive_message += (data + (CString)"\r\n"); 
    UpdateData(FALSE); 
    CWnd* wnd= GetDlgItem(IDC_EDIT_RECEIVE_MESSAGE); 
    wnd->PostMessage(WM_VSCROLL,SB_BOTTOM,0); 
} 
void CMessageSend::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{ 
    // TODO: Add your message handler code here and/or call default 

    CDialog::OnVScroll(nSBCode, nPos, pScrollBar); 
} 

bool BoundsCheck2(char *myTestArray, unsigned int expectedSize) 
{ 
    //Reference: Reference: http://lelanthran.com/deranged/?p=182 
    bool status = true; 
    unsigned int count = 0; 
    //perform bounds checkes on data1; just to be safe 
    for (size_t i = 0; i < sizeof(myTestArray)/sizeof(myTestArray[0]); i++)  { 
     count++; 
    } 
    if (count <= expectedSize) 
     status = true; 
    else 
     status = false; 
    return status; 
} 

MessageSend.h

#if !defined(AFX_MESSAGESEND_H__08C3FB4D_9E1E_4AF9_951F_7ED1033E3B16__INCLUDED_) 
#define AFX_MESSAGESEND_H__08C3FB4D_9E1E_4AF9_951F_7ED1033E3B16__INCLUDED_ 

#if _MSC_VER > 1000 
#pragma once 
#endif // _MSC_VER > 1000 
// MessageSend.h : header file 
// 

///////////////////////////////////////////CMessageSend dialog 

class CMessageSend : public CDialog 
{ 
// Construction 
public: 
    CMessageSend(CWnd* pParent = NULL); 
    void SetReceiveData(char* data); 
    // standard constructor 
// Dialog Data 
    //{{AFX_DATA(CMessageSend) 
    enum { IDD = IDD_DIALOG_MESSAGE }; 
    CString m_edit_message; 
    CString m_edit_receive_message; 
    //}}AFX_DATA 

    protected: 
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 

// Implementation 
protected: 
    virtual void OnOK(); 
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); 

    DECLARE_MESSAGE_MAP() 
}; 

#endif //  !defined(AFX_MESSAGESEND_H__08C3FB4D_9E1E_4AF9_951F_7ED1033E3B16__INCLUDED_) 

Jede Hilfe zu so viel ist geschätzt.

+3

Was ist 'TEXT'?Wie ist es initialisiert? Was ist "m_edit_message"? Wie ist es initialisiert? Ist der Aufruf von 'gethostname' erfolgreich? Meine * rate * ist, dass entweder 'TEXT' oder 'm_edit_message' nicht einfach C-String-Zeiger (oder Array) ist, sondern etwas wie ein 'CString'-Objekt, das nicht ohne explizite Umwandlung in eine C-style-Zeichenfolge verwendet werden kann Zeiger. –

+0

Auch was ist es? Bitte versuchen Sie, einen reproduzierbaren Fehler mit [Minimal, Complete und Verifable Beispiel] (http://stackoverflow.com/help/mcve) –

+0

Ich weiß nicht, was es ist, das ist eine Variable, die von VS erstellt/verwendet wird – Chris

Antwort

2

Ein Problem, das Sie haben in Ihrem Code, diesen Code:

bool BoundsCheck2(char *myTestArray, unsigned int expectedSize) 
// ... 
for (size_t i = 0; i < sizeof(myTestArray)/sizeof(myTestArray[0]); i++)  { 
    count++; 
} 

nicht tun, was Sie denken, sizeof(myTestArray)/sizeof(myTestArray[0] sind gleich 8 - immer (auch auf 32-Bit wäre 4 - Größe des Zeigers), Dies liegt daran, dass beim Aufruf einer Funktion mit Array-Argument der Zeiger auf das erste Element abfällt und die Größe des Arrays verloren geht.

Es ist auch schwer zu sagen, was diese Funktion tun soll, ist es zu überprüfen, ob der Compiler 50 Elemente Array erstellt? Sie sollten ihn besser vor der Verwendung initialisieren.

Eine andere Sache: Überprüfen Sie, ob Sie kompilieren mit UNICODE aktiviert sind, wenn dies der Fall ist CString ist wchar_t Zeichentyp.

Dieser Code:

CString textmsg; 
textmsg.Format("%s %s: %s",TEXT,comp, (CString) m_edit_message); 

ich umschreiben würde:

CString textmsg; 
textmsg.Format("%s %s: %s",TEXT.GetString(), comp, m_edit_message.GetString()); 

vorausgesetzt TEXT ist vom Typ CString - ich nehme an, es zu einem gewissen Widget gebunden ist?

auch:

char comp[50]; 

als:

char comp[256] = {0}; 

warum 256, lesen Sie hier: https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms738527(v=vs.85).aspx

letzte, was, immer Ergebniscodes für Win-API-Funktionen überprüfen, sonst könnte man wieder verwenden Daten im unbestimmten Zustand.

+0

Mit dieser Funktion habe ich versucht sicherzustellen, dass die an "myTestArray" übergebene Variable die Array-Größe 'expectedSize' nicht überschreitet. Daher kann sichergestellt werden, dass kein "Pufferüberlauf" auftritt – Chris

+0

@Chris - diese Funktion gibt immer wahr zurück (8 <50), – marcinj

+0

Ich verwende UNICODE, ich werde Ihren Vorschlag heute Abend umsetzen. Änderte auch die Prüfung auf '(size_t i = 0; i <= sizeof (myTestArray))' – Chris