none
Debug configuration always crush, but Release configuration behaves well(调试版本配置崩溃,发行版本配置正常) RRS feed

  • 问题

  • I want to give an educational demonstration how CFile and CArchive MFC classes cooperate together to simplify serialization. But the code always crushes while the project's configuration is in Debug mode. If I switch to Release mode, it behave well. Could any one give some hint? I paste the code as follows: (though not too much comments, but I think it will not hinder your conprehension, and any feedback is of great appreciation)

    我希望展示一下MFC的CFile类与CArchive类是如何结合起来完成序列化的,因此做了一个示例程序。但是这个程序在工程属性是调试版本的情况下会崩溃,但在发布版本时工作正常。不知是否有人能够给予指点?(我在下面贴出了代码,虽然注释不多,不过相信不会影响大家对功能的理解。任何关于此的反馈都不胜感激)


    #include "stdafx.h"

    #include <stdlib.h>

    #ifndef WIN32_LEAN_AND_MEAN
    #define WIN32_LEAN_AND_MEAN
    #endif

    #include <windows.h>

    // User-defined type for testing
    class str_t
    {
    public:
     str_t(){}
     str_t(char* psz)
     {
      pDat = NULL;
      if(psz)
       pDat = _strdup(psz);
      nLen = strlen(pDat);
     }
     ~str_t()
     {
      if(pDat)
       free(pDat);
     }
     char* pDat;
     int nLen;
    };

    // A simple wrapper for file operation
    class CMyFile
    {
    public:
     CMyFile(LPCTSTR lpszFilePath)
     {
      m_hFile = INVALID_HANDLE_VALUE;
      memset(m_szFilePath, 0, sizeof(m_szFilePath));
      _tcscpy_s(m_szFilePath, MAX_PATH - 1, lpszFilePath);
     }
     ~CMyFile()
     {
      if(m_hFile != INVALID_HANDLE_VALUE)
       Close();
     }
     bool Open(LPCTSTR lpszFilePath, DWORD dwCreateDisp)
     {
      if(!lpszFilePath)
       lpszFilePath = m_szFilePath;

      m_hFile = CreateFile(lpszFilePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
       dwCreateDisp, FILE_ATTRIBUTE_NORMAL, NULL);

      return m_hFile != INVALID_HANDLE_VALUE;
     }

     void Close()
     {
      CloseHandle(m_hFile);
      m_hFile = INVALID_HANDLE_VALUE;
     }

     int Read(void* pBuf, int nLen)
     {
      DWORD dwRead;
      ReadFile(m_hFile, pBuf, nLen, &dwRead, NULL);
      return dwRead;
     }

     int Write(void* pBuf, int nLen)
     {
      DWORD dwWritten;
      WriteFile(m_hFile, pBuf, nLen, &dwWritten, NULL);
      return dwWritten;
     }

     bool IsHandleValid()
     {
      return m_hFile != INVALID_HANDLE_VALUE;
     }
    private:
     HANDLE m_hFile;
     TCHAR m_szFilePath[MAX_PATH];
    };

    // The demonstrating delegate, or the intermedia
    class CMyArchive
    {
    public:
     CMyArchive(CMyFile file)
     {
      m_pFile = &file;
     }

     void BeginStore()
     {
      if(!m_pFile->IsHandleValid())
       m_pFile->Open(NULL, CREATE_ALWAYS);
     }

     void EndStore()
     {
      m_pFile->Close();
     }

     void BeginRetrive()
     {
      if(!m_pFile->IsHandleValid())
       m_pFile->Open(NULL, OPEN_EXISTING); 
     }

     void EndRetrive()
     {
      m_pFile->Close();
     }

     void operator << (int n)
     {
      m_pFile->Write(&n, sizeof(n));
     }
     void operator << (double d)
     {
      m_pFile->Write(&d, sizeof(d));
     }

     void operator << (str_t str)
     {
      m_pFile->Write(str.pDat, str.nLen);
     }

     void operator >> (int& n)
     {
      int t;
      m_pFile->Read(&t, sizeof(t));
      n = t;
     }
     void operator >> (double& d)
     {
      double t;
      m_pFile->Read(&t, sizeof(t));
      d = t;
     }
     void operator >> (str_t& str)
     {
      str.pDat = (char*)malloc(str.nLen + 1);
      memset(str.pDat, 0, str.nLen + 1);
      m_pFile->Read(str.pDat, str.nLen);
     }

    private:
     CMyFile* m_pFile;
    };

    int _tmain(int argc, _TCHAR* argv[])
    {
     CMyFile file(L"test");

     CMyArchive ar(file);

     int a = 1, c;
     double b = 2.5, d;

     str_t str("i love you");
     str_t str1;

     printf("Value of a is: %d\n", a);
     printf("Value of b is: %f\n", b);
     printf("Value of str is: %s\n", str.pDat);

     ar.BeginStore();
     ar << a;
     ar << b;
     ar << str;

     ar.EndStore();

     ar.BeginRetrive();
     str1.nLen = str.nLen;

     ar >> c;
     ar >> d;
     ar >> str1;

     ar.EndRetrive();

     printf("Value of c is: %d\n", c);
     printf("Value of d is: %f\n", d);
     printf("Value of str1 is: %s\n", str1.pDat);

     return 0;

    }

    This is the system information: OS: Windows 7 Home Basic; Build Tools Microsoft VS 2008

    我的操作系统是Windows 7 Home Basic; 构建工具是Microsoft VS 2008

     

    2010年6月26日 2:45

答案

全部回复

  •  
     
    • 已标记为答案 mingcraeer 2010年6月28日 2:00
    2010年6月26日 9:01
  • str_t的成员在使用之前没有初始化。Debug版会抓住这个bug

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    2010年6月27日 3:21
    版主
  • Dear 江写生:

    No more thanks for your detailed explainations, appreciate it very much!

    2010年6月28日 1:55