0

我的應用程序有一些調試代碼,專門用於在調試模式下運行時將調試數據發送到輸出窗口。當在下面的代碼片段中調用函數GetCurrTime時,如果我讓它自由運行,那麼當我逐句通過代碼或在調用malloc之前的行上時,應用程序會崩潰在以下調用中:malloc。然而,真正的奇怪之處在於,當碰撞發生時,PC不會落在這些線路中的任何一條上。 PC以完全不相關的功能停在返回線上。它變得更好了。調用堆棧顯示沒有地方讓函數返回。我猜測PC不知何故會進入雜草叢生。是什麼讓這一切真的很奇怪,是因爲當我打電話給GetCurrTime時,問題就消失了。當添加一個函數調用時,應用程序幻像崩潰

void PrintDevMsgTrace(LPBYTE pMsg, PWCHAR fnName) 
{ 
#ifdef _DEBUG 
    BYTE byMsgLen; 
    TCHAR * ptTimeStr = NULL; 
    WORD cmd; 
    int i, j = 0; 
    int iTimeStrLen, iStrLen, iPreOffset, iPostOffset; 
    wchar_t * pCmdIdStr = NULL; 
    wchar_t * pBuf = NULL; 

    byMsgLen = pMsg[DEV_LEN_OFFSET] + sizeof(devPktHead_t) + sizeof(devPktTail_t); 
    cmd = pMsg[DEV_CMD_MSB_OFFSET]; 
    cmd <<= 8; 
    cmd |= pMsg[DEV_CMD_LSB_OFFSET]; 
    pCmdIdStr = GetCmdIdStr(cmd); 
    ptTimeStr = GetCurrTime(); 
    iTimeStrLen = ::wcsnlen_s(ptTimeStr, 128); 
    iPreOffset = 
     iTimeStrLen        // time string 
     + 1          // "-" 
     + ::wcsnlen_s(fnName, 128)   // function name 
     + 3          // " : " 
     + ::wcsnlen_s(pCmdIdStr, 128)   // command ID string 
     + 3;         // " 0x" 
    iPostOffset = iPreOffset + byMsgLen * 3; // "%.2X " (formatted: 2 hex-nibble bytes and space) 
    iStrLen = iPostOffset + 3;     // "\r\n\0" 
    pBuf = (wchar_t *)::malloc(iStrLen * sizeof(wchar_t)); 

    ::swprintf_s(pBuf, iStrLen, _T("%s-%s : %s 0x"), ptTimeStr, fnName, pCmdIdStr); 

    for (i = iPreOffset; i < iPostOffset; i += 3) 
    { 
     ::swprintf_s(&(pBuf[i]), 4, _T("%.2X "), pMsg[j++]); 
    } 

    ::swprintf_s(&(pBuf[i]), 3, _T("\r\n")); 

    TRACE(pBuf); 

    ::free(pBuf); 
#endif 
} 

TCHAR * GetCurrTime(void) 
{ 
    DWORD dwError = ERROR_SUCCESS; 
    TCHAR * ptRetVal = NULL; 
#ifdef _DEBUG 
    int iTimeStrLen; 

    do 
    { 
     if ((iTimeStrLen = ::GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, NULL, 0)) == 0) 
     { 
      dwError = ::GetLastError(); 
      TRACE(_T("%s : Failed getting time format.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), _T(__FUNCTION__), dwError, _T(__FILE__), __LINE__); 
      continue; 
     } 

     if ((ptRetVal = (TCHAR *)::malloc(iTimeStrLen)) == NULL) 
     { 
      dwError = ERROR_NOT_ENOUGH_MEMORY; 
      TRACE(_T("%s : Not enough memory.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), _T(__FUNCTION__), dwError, _T(__FILE__), __LINE__); 
      continue; 
     } 

     if (::GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, ptRetVal, iTimeStrLen) == 0) 
     { 
      dwError = ::GetLastError(); 
      TRACE(_T("%s : Failed getting time format.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), _T(__FUNCTION__), dwError, _T(__FILE__), __LINE__); 
      continue; 
     } 
    } 
    while (0); 
#endif 

    if (dwError != ERROR_SUCCESS) 
    { 
     ::free(ptRetVal); 
     ptRetVal = NULL; 
    } 

    ::SetLastError(dwError); 

    return ptRetVal; 
} 

只是踢,這裏的功能,當碰撞發生在PC土地(該函數的最後一行return語句):

LPVOID CLinkList::Add(LPVOID pItem, DWORD len) 
{ 
    DWORD dwError = ERROR_SUCCESS; 
    LPVOID pItemCopy = NULL; 
    LPLIST_NODE_T ptNode = NULL; 

    do 
    { 
     // Validate parameters. 
     if ((pItem == NULL) || (len == 0)) 
     { 
      dwError = ERROR_INVALID_PARAMETER; 
      TRACE(_T("CLinkList::Add : Invalid parameter.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), dwError, _T(__FILE__), __LINE__); 
      continue; 
     } 

     if (this->m_blCopy == FALSE) 
     { 
      pItemCopy = pItem; 
     } 
     else if ((pItemCopy = ::malloc(len)) == NULL) 
     { 
      dwError = ERROR_NOT_ENOUGH_MEMORY; 
      TRACE(_T("CLinkList::Add : Failed to allocate memory.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), dwError, _T(__FILE__), __LINE__); 
      continue; 
     } 
     else 
     { 
      ::memcpy(pItemCopy, pItem, len); 
     } 

     if ((ptNode = (LPLIST_NODE_T)::malloc(sizeof(LIST_NODE_T))) == NULL) 
     { 
      dwError = ERROR_NOT_ENOUGH_MEMORY; 
      TRACE(_T("CLinkList::Add : Failed to allocate memory.\r\n\tError: %d\r\n\tFile: %s\r\n\tLine: %d\r\n"), dwError, _T(__FILE__), __LINE__); 
      continue; 
     } 

     ptNode->next = NULL; 
     ptNode->item = pItemCopy; 
     ptNode->len = len; 

     if (this->m_ptFirstNode == NULL) 
     { 
      ptNode->prev = NULL; 
      this->m_ptFirstNode = ptNode; 
     } 
     else 
     { 
      ASSERT(this->m_ptLastNode != NULL); 

      ptNode->prev = this->m_ptLastNode; 
      this->m_ptLastNode->next = ptNode; 
     } 

     this->m_ptLastNode = ptNode; 
     this->m_dwItemCount++; 
    } 
    while (0); 

    if (dwError != ERROR_SUCCESS) 
    { 
     ::free(ptNode); 

     if (this->m_blCopy != FALSE) 
     { 
      ::free(pItemCopy); 
     } 

     pItemCopy = NULL; 
    } 

    ::SetLastError(dwError); 

    return pItemCopy; 
} 

這是錯誤,因爲印刷在輸出窗口:0000005:在ZCT.exe 0x7c936822

第一次機會異常訪問 衝突讀取位置00000000。 HEAP [ZCT.exe]:缺少最後一個條目 堆在5451460附近提交範圍內 Windows觸發了一個斷點 ZCT.exe。

這可能是由於 堆,這表明在ZCT.exe 或任何它已加載的DLL的一個錯誤的損壞。

這也可能是由於用戶 在ZCT.exe有焦點時按下F12。

輸出窗口可能有更多 診斷信息。程序 '[0x9F4] ZCT.exe:Native'已退出 ,代碼爲0(0x0)。

任何想法?

+0

分配給'ptTimeStr'(也可能是'pCmdIdStr')的內存永遠不會被釋放,所以你在這裏有內存泄漏。我認爲Bo的回答如下是你當前的問題來自哪裏。 – 2011-06-03 16:15:38

回答

2
ptRetVal = (TCHAR *)::malloc(iTimeStrLen) 

將分配的時候,你可能要分配該號碼的wchar_t秒的字節數。

+0

ptRetVal =(TCHAR *):: malloc(iTimeStrLen * sizeof(TCHAR))我不確定是否不需要爲字符串malloc的末尾的空字符添加+1((iTimeStrLen + 1)* sizeof(TCHAR)) – David 2011-06-03 16:52:34

相關問題