2017-04-03 13 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

あなたは 'new char [fileSize/2 + 1]'のみを割り当てようとします。 –

答えて

2

ラインでdebug_heap.cppファイルにブレークポイントをヒットした直後にすべきですこれは、コードがバッファの終わりを超えて書き込むためです。

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

しかし、その後、あなたは、ファイルから fileSizeバイトを読み取ろうとする:あなたはこのよう bufferを割り当てます。あなたの割り当てではなく、次のようになります。

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

いくつかの他のコメント:

  • sprintf_sへのあなたの呼び出しはバッファオーバーランのリスク。
  • C++でコード化したので、std::stringを使用し、そのクラスでバッファを管理するようにしてください。 filePathbufferの両方でこれを行う必要があります。それはあなたの現在のコードが持っているリークを避けることができます。たとえば、ReadFileの後にエラーが戻った場合、メモリがリークします。そして、メモリの割り当てを解除するために、呼び出しコードに負担をかけないようにします。
  • コードがReadFileの後にエラーを返す場合は、ファイルハンドルもリークします。
  • bytesReadedは、正しい英語の単語を使用するには、bytesReadという名前にする必要があります。
  • 実行可能ファイルが現在の作業ディレクトリにあると考える本当の理由はありません。
+0

最終的な箇条書きについては、あなたの最後の質問では、おそらくそれは沈んでいないと言いました。現在のディレクトリは、必ずしも実行可能ファイルが置かれているディレクトリではありません。非常に頻繁に別のディレクトリです。 –

+0

彼はまた、ハンドルを漏らしている、より良いクラスまたは独自のポインタをカスタムdeleterでこれらのハンドルをラップします。 –

+0

どのようにハンドルが漏れていますか?ファイルへのハンドルは、関数の最後に閉じられます。 – Xor

関連する問題