対象書籍
猫でもわかるネットワークプログラミング 『猫でもわかるネットワークプログラミング』のサンプルコードに下記の事象が確認されています。
■対象プログラム
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; } |