CString Format()无法读取内存VS2015

CString Format() unable to read memory VS2015

我一直在收到消息 Error reading characters of string Unable to read memory。我不确定如何更正它,因为在调用 CString.Format() 函数时似乎一切都井井有条。

这是 strnlen.cpp 中发生错误的地方:

这里是休息时间的当地人:

这是调用 strnlen.cpp 的函数(最后一行是中断发生的地方):

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

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

m_edit_message 是一个 CString 变量。

最后是出错时的调用堆栈:

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_)

非常感谢对此的任何帮助。

你的代码有一个问题,这段代码:

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

没有按照你的想法去做,sizeof(myTestArray) / sizeof(myTestArray[0] 等于 8 - 总是(在 32 位上是 4 - 指针的大小),这是因为当你调用一个带有数组参数的函数时它会衰减指向其第一个元素的指针,数组的大小丢失。

也很难说这个函数是做什么的,它是在检查编译器是否创建了50个元素的数组?你最好在使用前对它进行零初始化。

另一件事:检查您是否在启用 UNICODE 的情况下进行编译,如果是,则 CString 是 wchar_t 字符类型。

此代码:

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

我会重写为:

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

假设 TEXT 是 CString 类型 - 我想它绑定到某个小部件?

还有:

char comp[50];

如:

char comp[256] = {0}; 

为什么是 256,请阅读此处:https://msdn.microsoft.com/pl-pl/library/windows/desktop/ms738527(v=vs.85).aspx

最后,始终检查 Win API 函数的结果代码,否则您可能会使用未确定状态的返回数据。