『猫でもわかるネットワークプログラミング』のサンプルコードに下記の事象が確認されています。
■対象プログラム
2.3節 GUI版HTTPクライアント html02.exe(p.22)
■事象
2回以上URL取得を実行した場合、プログラムの終了時に正常にメモリオブジェクトが解放されない。
■原因
メモリオブジェクトの解放処理がWM_CLOSEメッセージ発生時のみであるため、最後に取得したメモリオブジェクト以外は解放されない。
■改修方法
MyConnect関数は、下記のコードを使用してください。(改修ファイルのダウンロード html02b.lzh 17KB)
int MyConnect()
{
HINTERNET hInet, hUrl;
char szBuf[32];
DWORD dwRead;
HGLOBAL hTemp;
if (hMem != NULL) {
GlobalUnlock(hMem);
if (!(hMem = GlobalFree(hMem))) {
MessageBox(g_hWnd, "前回確保したメモリを解放しました。n"
"新たにメモリを確保します。",
"メモリ解放成功", MB_OK);
} else {
MessageBox(g_hWnd, "前回確保したメモリの解放に失敗しました",
"Error", MB_OK);
return -1;
}
}
hMem = GlobalAlloc(GHND, 1);
lpszSrc = (char *)GlobalLock(hMem);
if (lpszSrc == NULL) {
MessageBox(g_hWnd, "Error", "Error", MB_OK);
return -1;
}
int nTotal = 0;
hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, 0);
if (hInet == NULL) {
MessageBox(g_hWnd, "オープンエラー", "Error", MB_OK);
return -1;
}
hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0);
if (hUrl == NULL) {
MessageBox(g_hWnd, "URLオープンエラー", "Error", MB_OK);
InternetCloseHandle(hInet);
return -2;
}
while (1) {
InternetReadFile(hUrl, szBuf, (DWORD)sizeof(szBuf) - 1, &dwRead);
szBuf[dwRead] = '';
if (dwRead == 0)
break;
nTotal += dwRead;
hTemp = GlobalReAlloc(hMem, (SIZE_T)nTotal+1, GMEM_MOVEABLE);
if (hTemp == NULL) {
MessageBox(g_hWnd, "再アロケート失敗", "Error", MB_OK);
return -3;
}
hMem = hTemp;
lpszSrc = (char *)GlobalLock(hMem);
strcat(lpszSrc, szBuf);
}
InvalidateRect(g_hWnd, NULL, TRUE);
InternetCloseHandle(hUrl);
InternetCloseHandle(hInet);
return 0;
}
|