最近在寫一個讀取模型文件的小程序。很隨意的使用了strcpy函數進行char字符數組的拷貝,這個數組是需要傳遞給PostMessage作為WPARAM的參數。代碼部分如下:
1 char pStrCurrentFileName[MAX_PATH] = ""; 2 std::string strCurrentFileName; 3 4 //若是有效單個prt文件路徑,則直接讀取 5 if (IsValidModelPath(m_strInputPath)) 6 { 7 //此處省略部分代碼 8 9 strCurrentFileName = GetFileNameWithExt(m_strInputPath); 10 strcpy(pStrCurrentFileName, strCurrentFileName.c_str()); 11 ::PostMessage(m_hDlg, WM_USER_MSG_SHOWFILENAME, WPARAM(&pStrCurrentFileName), LPARAM(m_strInputPath.size())); 12 13 ReadFile(m_strInputPath); 14 15 //此處省略部分代碼 16 }
程 序在64位Debug下運行正常,編譯成64位Release後,雙擊exe運行,在執行到此部分後程序閃退,有時候會彈出一個提示對話框(忘記截圖 了),大概適合ntdll.dll有關。而且幾乎讀取所有模型都會出現這個問題。百度了ntdll.dll,原來所有的win32api函數都會調用該 dll,立刻聯系到增加的這個strcpy函數(由於用了svn,歷史版本也不多,回溯起來也方便^_^)。因為之前在使用strcpy時,也想到是不是 要使用memcpy函數,但當時沒怎麼考慮就用strcpy了。改用memcpy後,第10行代碼替換成:
memcpy(pStrCurrentFileName, strCurrentFileName.c_str(), strCurrentFileName.size());
release下運行再沒有出現崩潰的情況。直接搜百度“mfc程序release崩潰”,有篇文章正好有提到,現摘抄如下:
2.數據溢出的問題
如:
char buffer[10];
int counter;
lstrcpy(buffer, "abcdefghik");
如果您使用了strcpy(),lstrcpy() 等函數請注意檢查。
在 debug版中buffer的NULL覆蓋了counter的高位,但是除非counter>16M,什麼問題也沒有。但是在release版 中,counter可能被放在寄存器中,這樣NULL就覆蓋了buffer下面的空間,可能就是函數的返回地址,這將導致ACCESS ERROR。
3.DEBUG版和RELEASE版的內存分配方式是不同的 。
如 果你在DEBUG版中申請ele 為 6*sizeof(DWORD)=24bytes,實際上分配給你的是32bytes(debug版以32bytes為單位分配), 而在release版,分配給你的就是24bytes(release版以8bytes為單位),所以在debug版中如果你寫ele[6],可能不會有 什麼問題,而在release版中,就有ACCESS VIOLATE。
這篇文章的原文鏈接是:http://blog.csdn.net/fanwenbo/article/details/6067156
看來寫了程序後,還需要經常release下同時測試,很多在debug下沒有出現的問題會反映在release版中。
先記錄下,後面有時間再研究下這個問題。