データベースをリロードする度に、タスクマネージャの物理メモリの使用量がおよそ20MBずつ増えて行っています。
これがメモリリーク?だと思うのですが、対処法が判らずに居ます。。。
それと同時にメモリリークの主たる発生原因もわからずにいます。
これはきちんとメモリを開放出来ているのでしょうか?
また、メモリリークの発生箇所を調べる手法がありましたらご指導願います。
以下がデータベースを構築しているコードです
/////////////////////////////////////////////////////////////////////////////////////////////////////
//構造体名 :StrageStruct
//機能 :szStrageResultを分割した後の在庫情報を格納する
// :*SQLサーバー内のテーブルを変更した場合は此処もそれに沿って変更してください
// :バージョンアップさせても、クライアントとサーバーは同じ構造体を用いること
/////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct{
unsigned char **lpStrage; //在庫情報を格納する。配列を動的に確保するのでポインタへのポインタ(ヘッダ情報は含まない)
}DataBase;
/////////////////////////////////////////////////////////////////////////////////////////////////////
//関数名 :CutResult関数
//機能 :メインのResult構造体を更に分解してそれぞれの構造体に格納する
//引数 :Row = 格納したいデータと関連する行数を格納した数値を渡してください
// :Col = 格納したいデータと関連するカラム数を格納した数値を渡してください
// :lpDataBase = 目的のデータベースのポインタを渡してください
// :nSwitch = それぞれに対応するスイッチ番号を渡してください。
// : 1:在庫情報の切り分け処理 2:出荷情報 3:素板
//戻り値 :動作が完了すると0を返す
//備考 :
/////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename row,typename col,typename DATA>int DataHunger::CutResult(row BaseRow,col BaseCol,DATA **TempData,int nSwitch){
//strtokが一度でも実行されるとTURE
BOOL bFlag = FALSE;
SQLRESULT ResultCopy;
int i = 0,k = 0;
int nRow,nCol;
unsigned char *lpToken,*lpPoint;
char szBuff[ShipmentSize];
char *lpStr;
//strtokで破壊されるので構造体をコピーしておく
ResultCopy = Result;
//SQLエラーフラグがTRUEならば処理を中断する
//あとでインターフェイスを実装してください。
if(Result.SqlErrorFlag == TRUE){
//lpStr = CastTimeStr("SQLエラーが検出されました。データが欠損しています。\r\n");
//SendMessage(HWND_CONTROL::hEdit,EM_REPLACESEL,0,(LPARAM)lpStr);
return -1;
}
//行数とカラム数を取得しておく
nRow = ntohs(BaseRow);
nCol = ntohs(BaseCol);
//行数が0(データ無し)ならリターンする
if(nRow == 0){
return -2;
}
//構造体の配列を確保する
*TempData = new DATA[nRow + 3];
//構造体のメンバ変数をカラム数分確保する
//nRowに+1することで行数が多い場合のバグを回避
for(i = 0;i < nRow + 3;++i){
(*TempData)[i].lpStrage = new unsigned char * [nCol];
}
//構造体の全ての配列と、全てのメンバポインタに対して512個の要素数を与える
//nRowに+1することで行数が多い場合のバグを回避
for(i = 0;i < nRow + 3;++i){
for(k = 0;k < nCol;++k){
(*TempData)[i].lpStrage[k] = new unsigned char[512];
}
}
//変数初期化
i = 0;
k = 0;
//スイッチの切り替え処理
switch(nSwitch){
//在庫情報
case 1:
strncpy(szBuff,ResultCopy.szStrageResult,sizeof(szBuff));
break;
//出荷予定
case 2:
strncpy(szBuff,ResultCopy.szShipmentResult,sizeof(szBuff));
break;
//素板情報
case 3:
strncpy(szBuff,ResultCopy.szBoardResult,sizeof(szBuff));
break;
default:
return -3;
break;
}
//トークンに分解して構造体に格納する
while(true){
if(bFlag == FALSE){
lpToken = _mbstok((unsigned char *)szBuff,(const unsigned char *)"@");
wsprintf((LPSTR)(*TempData)[i].lpStrage[k],"%s",(LPSTR)lpToken);
//*注意!!!!!!!!!!!!!!!!!
//*(*引数)でダブルポインタの実態、すなわちポインタを示す。それにアロー演算子で参照している
//*わかりずらぃいいいいいいい!!!!!!!!!!!!!!!!!!!!!!
//MessageBox(NULL,(char *)(*TempData)[i].lpStrage[k],"",MB_OK);
}else{
lpToken = _mbstok(NULL,(const unsigned char *)"@");
//lpTokenがNULLならば抜ける
if(lpToken == NULL){
break;
}else{
sprintf_s((LPSTR)(*TempData)[i].lpStrage[k],512,"%s",(LPSTR)lpToken);
//MessageBox(NULL,(char *)(*TempData)[i].lpStrage[k],"",MB_OK);
}
}
bFlag = TRUE;
k++;
if(k == nCol){
i++;
k = 0;
}
}
//後始末
lpToken = NULL;
lpPoint = NULL;
memset(szBuff,0,sizeof(szBuff));
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//関数名 :ReleaseMemory関数
//機能 :確保したポインタをリリースする
//引数 :
//戻り値 :BOOL型、途中で失敗するとFalse
/////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename row,typename col,typename DATA>int DataHunger::ReleaseMemory(row BaseRow,col BaseCol,DATA **TempData){
int i,k;
int nRow;
int nCol;
if(*TempData == NULL)
return false;
//行数とカラム数を取得しておく
nRow = ntohs(BaseRow);
nCol = ntohs(BaseCol);
//512個の要素をそれぞれ開放
for(i = 0;i < nRow +3;++i){
for(k = 0;k < nCol;++k){
delete[] (*TempData)[i].lpStrage[k];
(*TempData)[i].lpStrage[k] = NULL;
}
}
//列の要素を開放
for(i = 0;i < nRow + 3;++i){
delete[] (*TempData)[i].lpStrage;
(*TempData)[i].lpStrage = NULL;
}
//構造体を開放
delete[] *TempData;
*TempData = NULL;
return true;
}