none
内存处理异常 RRS feed

  • 问题

  • LPVOID        m_lpBuffer;
    LPBYTE        m_lpBufferPos;
    int	  m_nBufferSize;
    
    struct msg_define
    {
    	WORD  messageLen;
    	WORD  messageTepyid;
    	int   recievemessageLen;
    };
    
    struct recieve_message
    {
    	BYTE  byMessageId;
    	std::string strMessageInfo;
    };
    
    std::map<BYTE,std::string>			mapMessageInfo;
    
    // nSize : 表示消息的总长度,msg_define: 表示消息结构体
    void ProcessRecieveMessage(int nSize,msg_define* pHeader)
    {
    	m_nBufferSize = nSize - sizeof(msg_define);
    	if (m_lpBuffer)
    	{
    		delete []m_lpBuffer;
    		m_lpBuffer = 0;
    	}
    	m_lpBuffer = new BYTE[pHeader->messageLen];
    	m_lpBufferPos = static_cast<LPBYTE>(m_lpBuffer);
    
    	CopyMemory(m_lpBufferPos,pHeader + 1,m_nBufferSize);
    
    	mapMessageInfo.clear();
    
    	size_t count = (size_t)m_nBufferSize/sizeof(recieve_message);
    	recieve_message* pRecieveMessage = static_cast<recieve_message*>(m_lpBuffer);
    	for (size_t i = 0; i < count; i++, pRecieveMessage++)
    		mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;
    }
    
    // 当结构体msg_define消息缓存区里面的内容为
    // 1(byMessageId),"四字成语"(strMessageInfo),2(byMessageId),“一惊一乍”(strMessageInfo)……
    // 这个模式(字节数一样),上面的语句运行的时候不会报错
    // 但是当改成1(byMessageId),"四字"(strMessageInfo),2(byMessageId),“一惊一乍”(strMessageInfo)……
    // 这种模式(字节数不一样且是汉字的时候),运行的时候会提示内存错误 (好像如果是英文的话,不会报错)
    // 不知道是为什么??? 请指教。
    2010年1月18日 3:31

答案

  • 怀疑是m_lpBuffer = new BYTE[pHeader->messageLen];
    这句pHeader->messageLen太大了,导致无法分配内存。
    麻烦把正确答案设为解答。
    2010年1月19日 1:04
    版主
  • 同意SplendourG的说法,这个可能是由于new操作失败抛出的异常。如果new操作失败的话,在Visual C++ .NET下,非MFC项目会抛出std::bad_alloc异常,MFC的项目会抛出CMemoryException异常。原因可能是pHeader->messageLen太大或者是它本身就没有被赋值。

    可以参考一下MSDN的文章:

    http://msdn.microsoft.com/en-us/magazine/cc164087.aspx


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2010年1月25日 7:42
  • 异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句抛的呢,还是在new BYTE[pHeader->messageLen];这一句抛的?你这里好像就这两句能抛std::bad_alloc异常。
    在这两句上加个断点试试,看看是那一句抛的。
    另外,是不是改了以后总是会抛异常,而原来那样就不抛呢?
    另外,直接从二进制流里面摘对象也太危险了,不能用别的办法吗?
    LHL
        异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句
    每次都是在 i = count - 1 的时候,就抛出异常了。
    怀疑你的nSize - sizeof(msg_define)不等于pHeader->messageLen;可能大于。这段程序中能出问题的地方太多了,不确定因素也太多了,比如说你的那个消息块是怎么生成的?里面的数据都对吗?很难说是怎么回事,只能单步调试,看看变量都有些什么变化。std::bad_alloc这种异常好像真的很难碰到,你即便申请4G的内存也不一定会有这个异常,程序可能会停止响应而已。我没在C++中做过实验,在C中如果用malloc分配2G内存,程序会停止响应,CPU占到100%。我看过C++Release模式下的默认operator new函数,内存分配是这么写的
    do{
    } while((malloc(size) == NULL));
    哈哈,真是这么写的,你在release模式下到汇编窗口下单步调试进入new函数后就是这样的。
    LHL
    2010年2月3日 1:46

全部回复

  • 能定位到错误的行么? 代码写得不太能看得懂,不知道你代码的目的是要做什么?
    2010年1月18日 3:51
    版主
  • 能定位到错误的行么? 代码写得不太能看得懂,不知道你代码的目的是要做什么?
    提示的错误是:…….exe 中的 0x7c812afb 处未处理的异常: Microsoft C++ 异常: 内存位置 0x0012bdc4 处的 std::bad_alloc。
    代码的目的就是服务端把一长串的recieve_message信息发送给客服端。
    2010年1月18日 4:48
  • 怀疑是m_lpBuffer = new BYTE[pHeader->messageLen];
    这句pHeader->messageLen太大了,导致无法分配内存。
    麻烦把正确答案设为解答。
    2010年1月19日 1:04
    版主
  • 同意SplendourG的说法,这个可能是由于new操作失败抛出的异常。如果new操作失败的话,在Visual C++ .NET下,非MFC项目会抛出std::bad_alloc异常,MFC的项目会抛出CMemoryException异常。原因可能是pHeader->messageLen太大或者是它本身就没有被赋值。

    可以参考一下MSDN的文章:

    http://msdn.microsoft.com/en-us/magazine/cc164087.aspx


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    2010年1月25日 7:42
  • <好像如果是英文的话,不会报错>!!!!!!
    内存开小了。
    并不是new 失败了
    2010年1月26日 2:23
  • 异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句抛的呢,还是在new BYTE[pHeader->messageLen];这一句抛的?你这里好像就这两句能抛std::bad_alloc异常。
    在这两句上加个断点试试,看看是那一句抛的。
    另外,是不是改了以后总是会抛异常,而原来那样就不抛呢?
    另外,直接从二进制流里面摘对象也太危险了,不能用别的办法吗?
    LHL
    2010年2月2日 8:42
  • 异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句抛的呢,还是在new BYTE[pHeader->messageLen];这一句抛的?你这里好像就这两句能抛std::bad_alloc异常。
    在这两句上加个断点试试,看看是那一句抛的。
    另外,是不是改了以后总是会抛异常,而原来那样就不抛呢?
    另外,直接从二进制流里面摘对象也太危险了,不能用别的办法吗?
    LHL
        异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句
    每次都是在 i = count - 1 的时候,就抛出异常了。
    2010年2月2日 11:33
  • 我想问题应该是出在mapMessageInfo上,你可以跟踪一下,看看mapMessageInfo和pRecieveMessage的具体值应该不难排除

    2010年2月2日 15:02
  • 异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句抛的呢,还是在new BYTE[pHeader->messageLen];这一句抛的?你这里好像就这两句能抛std::bad_alloc异常。
    在这两句上加个断点试试,看看是那一句抛的。
    另外,是不是改了以后总是会抛异常,而原来那样就不抛呢?
    另外,直接从二进制流里面摘对象也太危险了,不能用别的办法吗?
    LHL
        异常是在mapMessageInfo[pRecieveMessage->byMessageId] = pRecieveMessage->strMessageInfo;这一句
    每次都是在 i = count - 1 的时候,就抛出异常了。
    怀疑你的nSize - sizeof(msg_define)不等于pHeader->messageLen;可能大于。这段程序中能出问题的地方太多了,不确定因素也太多了,比如说你的那个消息块是怎么生成的?里面的数据都对吗?很难说是怎么回事,只能单步调试,看看变量都有些什么变化。std::bad_alloc这种异常好像真的很难碰到,你即便申请4G的内存也不一定会有这个异常,程序可能会停止响应而已。我没在C++中做过实验,在C中如果用malloc分配2G内存,程序会停止响应,CPU占到100%。我看过C++Release模式下的默认operator new函数,内存分配是这么写的
    do{
    } while((malloc(size) == NULL));
    哈哈,真是这么写的,你在release模式下到汇编窗口下单步调试进入new函数后就是这样的。
    LHL
    2010年2月3日 1:46
  • 结构体 struct recieve_message 中的成员 std::string strMessageInfo,不是一个简单内存块对象。

    它不可以用recieve_message* pRecieveMessage = static_cast<recieve_message*>(m_lpBuffer); 这样的方式访问。

    简单的举一个例子:

    BYTE buffer[256] = {'\0','1','2','3','4',0};


    recieve_message* pRecieveMessage = static_cast<recieve_message*>(buffer);

    pReceiveMessgae->strMessageInfo 并不保证是 "1234"这个字符串。 这与std::string对象的实现有关。

    如果你测试的话,也许碰巧是,但是,如果你再继续填充buffer的内容到足够的长度,将肯定得到其它的结果。

    2011年3月30日 17:24