CString Format()无法读取内存VS2015

时间:2016-04-16 16:10:43

标签: c++ mfc visual-studio-2015 c-strings

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

这是strnlen.cpp中发生错误的地方: enter image description here

以下是休息时的当地人: enter image description here

这是调用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_)

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您的代码中存在一个问题,此代码:

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函数的结果代码,否则你可能会使用未确定状态的返回数据。