2017-04-03 101 views
0

這個功能應該從文件中讀取字符串並返回,但調用ReadFile的程序後,立即在985線調用ReadFile的程序後命中斷點debug_heap.cpp

char* readFile() 
{ 
char curDirectory[MAX_PATH]; 
GetCurrentDirectory(MAX_PATH, curDirectory); 

char filePath[MAX_PATH]; 

char *name = "\\data.txt"; 

sprintf_s(filePath, "%s%s", curDirectory, name); 

HANDLE hFile = CreateFile(filePath, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 

if (hFile == INVALID_HANDLE_VALUE) 
{ 
    DisplayError("Can't Create File"); 
    return NULL; 
} 

DWORD fileSize = GetFileSize(hFile, NULL); 

char *buffer = new char[fileSize/2 + 1]; 
DWORD bytesReaded; 

if (ReadFile(hFile, buffer, fileSize, &bytesReaded, NULL) == 0) 
{ 
    DisplayError("Can't read File"); 
    return NULL; 
} 

buffer[bytesReaded] = '\0'; 

CloseHandle(hFile); 

return buffer; 
} 
+0

您嘗試讀取'fileSize'但你只分配'新的char [檔案大小/ 2 + 1]' –

回答

2

命中斷點debug_heap.cpp文件這是因爲你的代碼超出了緩衝區的末尾。您分配buffer這樣的:

char *buffer = new char[fileSize/2 + 1]; 

但是當你試圖從文件讀取fileSize字節。你的配置應該改爲:

char *buffer = new char[fileSize + 1]; 

一些其他意見:

  • 您對sprintf_s通話風險緩衝區溢出。
  • 由於您使用C++編寫代碼,因此請使用std::string並讓該類管理緩衝區。您應該爲filePathbuffer這樣做。這將允許您避免當前代碼的泄漏。例如,ReadFile泄漏內存後失敗返回。它避免了在調用代碼上釋放內存的負擔。
  • 如果您的代碼在ReadFile之後將失敗返回,您還會泄漏文件句柄。
  • bytesReaded應該命名爲bytesRead,使用正確的英文單詞。
  • 沒有真正的理由相信可執行文件位於當前工作目錄中。
+0

有關最後的子彈點,我告訴你,你的最後一個問題,但也許它沒有下沉。當前目錄並不總是可執行文件所在的目錄。很多時候它是一個不同的目錄。 –

+0

他也在泄漏手柄,用自定義刪除器的類或唯一指針更好地包裝這些手柄。 –

+0

我如何泄漏手柄?文件句柄在函數結束時關閉。請看 – Xor