メモリリーク?

[戻る]
なべ使い 2015/09/09(水) 22:41:24
こんばんわ、なべ使いと申します。

Windows7でVC++2010expressの環境で現在、前任者からPICマイコンとUSB通信を行うアプリケー
ションを引き継いで設計しています。
PICマイコンから100ms毎にデータを抜き取りアプリで表示し、logとしてCSVに保存しています。
段々とメモリ(プライベートワーキングセット)が増えいき、10分を過ぎるとlogのデータ数がす
くなくなっていきます。
原因として、メモリリークではないかと思い、動的メモリの確保しているmalooc、newを調べる
とUSBがPICとの接続するときだけに使用しているだけで、そのほかに動的なメモリは使用してい
なく、どのような原因でこのようなことが起きるのでしょうか。
PICとの通信で常時使用するのは、書き込みは、WriteFile(WriteHandle, &OutputPacketBuffer, 
65, &BytesWritten, 0);関数を用いて、読み込みは、ReadFile(ReadHandle, 
&InputPacketBuffer, 65, &BytesRead, 0);関数を使用し、バッファは、OutputPacketBuffer、
InputPacketBuffer共にグローバル変数としています。

情報として不足がありましたら、追加いたしますので
すみませんが、ご教示の程宜しくお願い致します。

仲澤@失業者 2015/09/10(木) 10:14:43
回答ではありません。あしからず。
手元にExpressもCommunityも無くて確かめられないのですが、
デバッグビルドならばメモリーリークを検出できたと記憶してますが、
Expressはできなかったでしたっけ。

なべ使い 2015/09/10(木) 11:20:33
一応メモリリーク検出できるか以下のサイトを参考して、やってみましたが、出力表示
は、「プログラム '[6844] *****.exe: マネージ (*****)' はコード 0 (0x0) で終了
しました。」とだけしか出ませんでした。
メモリリーク検出が行われていたらMemoryLeakCheck.exeなどと出るらしいので・・・
多分Expressでは、出来ないのではないかと思ってます。また、2008expressは出来ない
と記載されていました。

メモリリーク参考HP:http://urashita.com/archives/1271
2008express未対応参考HP:https://msdn.microsoft.com/ja-
jp/library/e5ewb1h3(v=vs.90).aspx

すみませんが宜しくお願い致します。

ITO 2015/09/10(木) 13:45:15
うーーん、
PICの形名はなんですか?
旧型PICだと、USBN9604等を使っている場合があります。
USBN9604等を使ったUSBのドライバーは、WINDOWS7に対応しないと思います。
確かめてみたほうがいいですね。
マイクロチップ社のドライバーやWINUSBを使っていればokです。
WriteFile/ReadFileはオーバラップI/Oで使った方がいいですね。
処理が終わらないうちにウインドウが閉じると、メモリーリークが発生します。

なべ使い 2015/09/10(木) 16:24:54
ITOさんありがとうございます。

PICの形名は、PIC24FJ64GB00になります。ドライバは、多分マイクロチップ社のを使用
していると思われます。前任者から引き継ぎの為、確かな情報はありませんが・・・


WriteFile/ReadFileのオーバラップI/Oについては、ちょっと確認してみます。

なべ使い 2015/09/13(日) 00:00:41
ITOさん
ちょっと教えてください。
WriteFile/ReadFileのオーバーラップI/Oは、まだ未実施なんですが、オーバーラップしない場
合は、処理が終わらないうちにウインドウが閉じるとメモリリークが発生するとありますが、詳
しく教えて頂けないでしょうか。
オーバーラップしないと、ずーと待ち状態になるからウインドウは閉じない様に思えるのです
が、違うのでしょうか。

宜しくお願い致します。

ITO 2015/09/14(月) 10:21:41
>オーバーラップしないと、ずーと待ち状態になるからウインドウは閉じない様に
>思える>のですが、違うのでしょうか。
 ソフトの利用方法で変わると思いますが、通常待ち状態にならないように通信処理は
スレッドで動かします。
 スレッドで動かすと待ち状態でもウインドウは閉じてしまうので、メモリリーク
が発生してしまいます。

 なので、WriteFile/ReadFileは、待ち状態にならないようオーバーラップI/Oで
動かします。

なべ使い 2015/09/14(月) 23:26:12
ITOさんありがとうございます。
スレッドで動かすと待ち状態でもウインドウが閉じてしまうからオーバーラップI/Oによりメモ
リリークを発生させないようにすると言うことなんですね。
なるほど、ありがとうございます。
今回、私が引き継いだソフトは、特にスレッドは使ってない様に思えます。PICとのデータ通信
が主で、そのデータを演算して、グラフ表示してlogとして保存するようなものです。あとは、
ボタン操作でpic側の設定変更になります。
スレッドでないソフトでメモリ(プライベートワーキングセット)が増えていく原因は何でしょう
かね。

すみませんが、ご教示の程宜しくお願い致します。

ITO 2015/09/15(火) 09:54:53
 通信が主なのにグラフ表示も行う、処理を考えるとスレッド化も考慮に入れたほうが
いいと思います。
 僕は使ったことがないですが、winusbで専用関数を使う方法があるみたいです。
それを使えば、オーバーラップI/Oを使わずにタイムアウト機能を設けることが出来る
可能性はあると思います。
>スレッドでないソフトでメモリ(プライベートワーキングセット)が増えていく原因は何
>でしょうかね。
この処理状況だと通信処理で受信したデータを new・malloc等で確保したメモリーに
一時保存している可能性がありますね。
そこらへんのメモリ処理はどうなっていますか?

みい 2015/09/15(火) 12:00:56
グラフ表示もしているなら、グラフ表示の方が原因という可能性もありませんか。
仮にグラフ表示部分をコメント化しても現象は変わりませんか?

なべ使い 2015/09/15(火) 15:01:33
ITOさん、みいさんありがとうございます。

タイマーイベントの中でWriteFile/ReadFileで通信処理したあとは、特にnew、malloc
はしないローカルの配列に入れてます。
そこから、ファイルへ書込み(StreamWriter()関数)、グラフ描画(AddXY()関数)を行っ
ています。

グラフをコメントアウトして、動作させると、今までlogデータは10分過ぎると段々と
少なくなって行きましたが、1時間半経ってもデータ数は変わらなくなりました。
ただ、やはりメモリは、少しづつ増えて行ってます。

データ数が変わらくなったのは、処理内容が多すぎてタイマーイベントに追いついてい
けてなかったからでしょうか。
これをマルチスレッドにするとデータ数を減らさず、通信が出来よう様になるのでしょ
うか。
マルチスレッドは、使ったことがないのですが、難しいのでしょうか。

みい 2015/09/15(火) 15:53:42
> グラフをコメントアウトして
AddXY()関数をコメントアウトされたのでしょうか。
AddXYし続けていったら内部保持のデータ量が
増えていきますので、使用メモリはどんどん増えていきます。

グラフには全部のデータを表示しているのでしょうか。
であれば、マルチスレッドにして描画処理の負荷を
通信に影響しないようにしても、どんどん負荷&使用メモリ
が増加していつか通信に影響を及ぼす可能性があります。
一定期間のものだけ描画するのであれば一定量を超えたら
一旦クリアして表示期間分だけセットする等工夫が必要です。

みい 2015/09/15(火) 16:53:15
> 一定期間のものだけ描画するのであれば
訂正
一定期間のものだけ描画するようにして

なべ使い 2015/09/15(火) 19:04:34
みいさんありがとうございます。
グラフ描画のコメントアウトは、AddXY()関数になります。
ずーとAddXY()関数を続けると使用メモリが増えていく・・・
コメントアウトしたのに、メモリが増えて行くのとは別に、このグラフ描画でも増えて
いたということですね。
このグラフ描画を一定期間のものだけを描画するようにすると、このグラフ描画でのメ
モリが増えていくことがなくなるということでしょうか。
今、データが常に末尾に追加されているのを一定期間毎に描画するようにすると言うこ
とでしょうか。

ITO 2015/09/15(火) 19:17:11
うーーん、
 グラフの場合、規模を考慮して最大メモリ容量を決めてしまうのも手です。
 多い場合はnew等を使うことも必要です。
 容量可変型の変数を使うと失敗しやすいと思います。
 データを何件・何千件表示するか利用者と決めておいた方がいいです。
 必要な件数まできたら、保存を行うようにして、また0件から取得する。
 データはCSV形式でエクセル等で使えるようにしておけばいいと思います。
以上でどうでしょうか?

ITO 2015/09/15(火) 19:47:57
グラフの件の案を出しましたが、
まず、

>データ数が変わらくなったのは、処理内容が多すぎてタイマーイベントに追いついてい
>けてなかったからでしょうか。
これを解決しないとまずいですね。

グラフ処理を止めて、タイマー時間を増やしていくとどうなりますか?
>1時間半経ってもデータ数は変わらなくなりました。
>ただ、やはりメモリは、少しづつ増えて行ってます。
これはどうなりますか?

なべ使い 2015/09/15(火) 23:13:52
ITOさん みいさん ありがとうございます。

グラフ処理をコメントアウトして、タイマー時間100msを200ms、400msにしていくとどうなるか
を試して見ます。
あとグラフの表示する方法として、どうしてもリアルタイムに見えるように、数値表示に追従す
るような形で描画する場合、AddXY()関数は使用メモリをどんどん増やしていくとありました
が、10分程度であればデータ数のも減少しないでいけると思いますので、5分に1回の割合でメモ
リのリフレッシュは出来ないでしょうか。

みい 2015/09/16(水) 11:59:18
グラフの描画には何を使用されていますか。
Chartコントロールだったら
 http://ar4pro.exblog.jp/tags/C%23/
C#だけど、少し参考になるかも

Addしたポイントデータはグラフ内部で保持されていると
思われますので、不要なポイントを削除していかないと
いけないと思います。
全クリアしかないのであれば、描画用のデータ領域用意して
そこにデータセットしておいて、フルスケールになったら
一旦全クリアしてその領域からデータセットし直すとか。
ただしAddXYの度に描画イベントがはしるからセットしている
間描画を止めないととかちらつきとかいろいろ出てくるかも。

むか〜し自力描画してた時は1ピクセル分ビットマップを
横にずらして1ピクセル分描画してました(^^;)

なべ使い 2015/09/16(水) 18:42:45
みいさん ITOさん ありがとうございます。

グラフ描画を1000ポイントごとにでクリア(chart1->Series[0]->Points->Clear();)す
ることでグラフ描画してもlogデータ数は、2時間程度動作させた位では減少することは
なくなりました。
ただ、やはり、メモリは徐々に増えて行ってます。

グラフなしでタイマー時間を200ms、400msにしても若干ゆっくりに見えますが、メモリ
は増加しています。

タイマーイベントの処理内容でメモリ増加をしているのがあるということですよね。

ITO 2015/09/16(水) 19:08:08
こういうのもあったけど
http://nanoappli.com/blog/archives/2577

http://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1575

パフォーマンスモニターだけが正しいわけでもないみたいですね。

ITO 2015/09/16(水) 19:15:04
>タイマーイベントの処理内容でメモリ増加をしているのがあるということですよね
そうですね、もう一度タイマーイベントの処理を調べてみたらどうでしょうか?

ITO 2015/09/16(水) 19:20:19
追記
PIC側のシフト開発者とは連絡取れないのでしょうか?
一度、通信フローも見直した方がいいかも知れないです。
本当にタイマーイベント内で処理できるのかも調べたほうがいいと思います。
あと、1s,2s.....ではどうなりますか?
それで落ち着くのなら、スレッド化を考えたほうがいいと思います。

ITO 2015/09/16(水) 19:42:00
修正です。
PIC側のソフト開発者とは連絡取れないのでしょうか?
です。

なべ使い 2015/09/17(木) 23:37:36
タイマーイベントの処理を一度コマンドデータのWriteFile(WriteHandle, 
&OutputPacketBuffer,65, &BytesWritten, 0);と受信データの
ReadFile(ReadHandle,&InputPacketBuffer, 65, &BytesRead, 0);関数だけにして行ったところ
メモリの増加は止まった様に思えます。
そうすると、PICとの通信フローは問題ない様に思えるのですが・・・
因みにPICのソフト担当者は私です。システム全体を引き継いだので・・・
次は、タイマーイベントの処理内容をひとつひとつコメントアウトして、潰していこうかと思っ
ています。
受信データ後の処理は、受信データの配列保存、データ表示用の演算、データ表示、データの
csvファイル保存、グラフ描画になります。

もし、スレッド化する場合は、結構大変なのでしょうか。

ITO 2015/09/18(金) 19:09:14
>タイマーイベントの処理を一度コマンドデータのWriteFile(WriteHandle, 
>&OutputPacketBuffer,65, &BytesWritten, 0);と受信データの
>ReadFile(ReadHandle,&InputPacketBuffer, 65, &BytesRead, 0);
>関数だけにして行ったところ
>メモリの増加は止まった様に思えます。

>そうすると、PICとの通信フローは問題ない様に思えるのですが・・・
ならよかったです。
問題あると、通信フローの見直し等大変です。

>もし、スレッド化する場合は、結構大変なのでしょうか。
仕上がっているソフトを変えるのは大変だと思います。
 ただ、フロー等、資料があるみたいですので、ひとつひとつ確認しながら
組み立てていけば意外とスム−ズにいくかもしれませんね。

スレッド化検討は、
 受信データの配列保存、データ表示用の演算、データのcsvファイル保存
の中で処理が詰まっているのをするのがいいと思います。
データ表示、グラフは見るうえでの不具合がない限り、遅いタイミング
でいいと思います。

なべ使い 2015/09/26(土) 11:23:21
少し、間が空いて仕舞いましたが、何と無く分かってきました。
メモリが段々増えて行くのは、グラフ描画と常にUSBの接続確認をするための関数と分かりまし
た。グラフに関しては、ある一定範囲の描画とするとグラフ描画によるメモリ増加は、無くなりま
した。あとは、USBの接続確認ですが、ここでの接続確認は、最初にUSB機器に接続する為に使用
している関数と同じ関数を名前替えて作り、その関数を常に通るようにして、USB機器が接続して
いるかを確認してました。
これについて何処でメモリリークしているかを確認中です。
USBに関する部分は、かなり高度なので、ご教示頂ければと思います。
ソースは、ここに記載しても良いのでしょうか。

ITO 2015/09/26(土) 19:09:03
たぶんいいと思いますが、あまり長いようだと嫌がる方がいますね。

なべ使い 2015/09/26(土) 21:18:40
ソースは、以下のサイトのPIC18 汎用クラス Microchip社デモソフト(WinUSBドライバ編)の
System::Void Connect_btn_Click(System::Object^  sender, System::EventArgs^  e)  関数部
分と同じになります。
 
http://www.ys-labo.com/VC%20Tips/2009/VC%20Tips%20USB.html

なべ使い 2015/09/28(月) 17:25:44
以下のソースになり、mallocをFreeにしてもまだリークしています。
このconnect_check関数を使用せずに、定期的にUSBデバイスが接続されているかを確認す
る方法はありませんでしょうか。

void Connect_check( void )
{
    GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00,
 0x11, 0x11, 0x00, 0x00, 0x30}; 
    HDEVINFO DeviceInfoTable = INVALID_HANDLE_VALUE;
    PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFA
CE_DATA;
    PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP
_DEVICE_INTERFACE_DETAIL_DATA;
    SP_DEVINFO_DATA DevInfoData;
    DWORD InterfaceIndex = 0;
    DWORD StatusLastError = 0;
    DWORD dwRegType;
    DWORD dwRegSize;
    DWORD StructureSize = 0;
    PBYTE PropertyValueBuffer;
    bool MatchFound = false;
    DWORD ErrorStatus;
    String^ DeviceIDToFind;
    DeviceIDToFind = MY_DEVICE_ID_24F;
    DeviceInfoTable = SetupDiGetClassDevsUM(&InterfaceClassGuid, NULL, NULL,
 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    while(true)
    {
        InterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA
);
        if(SetupDiEnumDeviceInterfacesUM(DeviceInfoTable, NULL, &Interfa
ceClassGuid, InterfaceIndex, InterfaceDataStructure))
        {
            ErrorStatus = GetLastError();
            if(ERROR_NO_MORE_ITEMS == ErrorStatus)
            {
                SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
                return;        
            }
        }else{
            timer1->Enabled = false ;
            Connect_Error = true;
            ErrorStatus = GetLastError();
            SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
            //メッセージ表示
            MessageBox::Show(" 接続が切れました。","WARNING",Messag
eBoxButtons::OK,MessageBoxIcon::Warning);
            return;    
        }
        DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
        SetupDiEnumDeviceInfoUM(DeviceInfoTable, InterfaceIndex, &DevInf
oData);
        SetupDiGetDeviceRegistryPropertyUM(DeviceInfoTable, &DevInfoData
, SPDRP_HARDWAREID, &dwRegType, NULL, 0, &dwRegSize);
        PropertyValueBuffer = (BYTE *) malloc (dwRegSize);
        if(PropertyValueBuffer == NULL)
        {
            SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
            return;        
        }
        SetupDiGetDeviceRegistryPropertyUM(DeviceInfoTable, &DevInfoData
, SPDRP_HARDWAREID, &dwRegType, PropertyValueBuffer, dwRegSize, NULL);
        #ifdef UNICODE
        String^ DeviceIDFromRegistry = gcnew String((wchar_t *)PropertyV
alueBuffer);
        #else
        String^ DeviceIDFromRegistry = gcnew String((char *)PropertyValu
eBuffer);
        #endif

        free(PropertyValueBuffer);
        DeviceIDFromRegistry = DeviceIDFromRegistry->ToLowerInvariant();
    
        DeviceIDToFind = DeviceIDToFind->ToLowerInvariant();        
        
        MatchFound = DeviceIDFromRegistry->Contains(DeviceIDToFind);    
    
        if(MatchFound == true)
        {
            DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVIC
E_INTERFACE_DETAIL_DATA);
            SetupDiGetDeviceInterfaceDetailUM(DeviceInfoTable, Inter
faceDataStructure, NULL, NULL, &StructureSize, NULL);    
            DetailedInterfaceDataStructure = (PSP_DEVICE_INTERFACE_D
ETAIL_DATA)(malloc(StructureSize));
            if(DetailedInterfaceDataStructure == NULL)
            {
                SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
                return;        
            }
            DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVIC
E_INTERFACE_DETAIL_DATA);
            SetupDiGetDeviceInterfaceDetailUM(DeviceInfoTable, Inter
faceDataStructure, DetailedInterfaceDataStructure, StructureSize, NULL, NULL); 
            WriteHandle7 = CreateFile((DetailedInterfaceDataStructur
e->DevicePath), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EX
ISTING, 0, 0);
            ErrorStatus = GetLastError();
            //if(ErrorStatus == ERROR_SUCCESS)
                //ToggleLED_btn->Enabled = true;
            ReadHandle7 = CreateFile((DetailedInterfaceDataStructure
->DevicePath), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXIS
TING, 0, 0);
            ErrorStatus = GetLastError();
            if(ErrorStatus == ERROR_SUCCESS)
            {}                    
            SetupDiDestroyDeviceInfoListUM(DeviceInfoTable);
            return;
        }
        InterfaceIndex++;
    }
}

ITO 2015/09/28(月) 18:15:12
Connect_checkの関数中のCreateFileは、でオ−プンしたハンドルはクローズしています
か?

 Connect_checkは一回だけ実行すればいいですね。

K 2015/09/28(月) 18:31:07
    PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new 
SP_DEVICE_INTERFACE_DATA;
    PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new 
SP_DEVICE_INTERFACE_DETAIL_DATA;

ここ↑で new しているのを delete しないまま関数を抜けているようですが、
構わないのでしょうか?

後者の DetailedInterfaceDataStructure は、
delete しないまま malloc() して上書きし、
さらに free() せずに関数を抜けているようですが、
構わないのでしょうか?

C++/CLI の new って、自動的に解放してくれるんでしょうか?
それはそれで(普通のC++の感覚だと)恐ろしいような気もしますが・・・

なべ使い 2015/09/28(月) 23:56:30
ITOさん、Kさんありがとうございます。

このソース含む他でもCreateFileに対してのclosehandleはしていないです。
この場合、closehandleするのは、どこが適当なのでしょうか。return;の前位でしょうか。
また、Connect_checkは、1回だけで良いとありますが、接続時にこれと同じ内容のconnect関数
を1回行い、定期的な接続確認の為にConnect_check関数を使用しています。
このConnect_checkをコメントアウトすると接続しているデバイスの電源を切っても接続の切断
情報をPOPアップ表示することが出来なくなってしまいます・・・。
本来は、接続しているデバイスの電源が切れたときは、どの様に認識して表示するのでしょう
か。

みい 2015/09/29(火) 09:16:18
> C++/CLI の new って、自動的に解放してくれるんでしょうか?
gcnewは自動解放だけど、newは普通のC++と同じに明示的に解放
しないといけなかったはず。

> 本来は、接続しているデバイスの電源が切れたときは、どの様に認識して表示するので
しょう
> か。
私は読み書きに失敗した時に1回Closeした後再度接続処理して…とかやってます。

なべ使い 2015/09/29(火) 10:38:03
みいさんありがとうございます。

まず、CloseHandleについては、 if(MatchFound == true)を抜けたInterfaceIndex++;
の所で行いました。
InterfaceDataStructureの解放に関しては、WriteHandle7 = CreateFile((.....の下で
deleteしましたが、DetailedInterfaceDataStructureの解放はどのようにすれば良いの
でしょうか。
Kさんが言うようにdeleteせずにmaloocで上書きしていますが・・・
この場合は、最後のmalloc後でfreeすれば良いのでしょうか。もしくは、mallocで使わ
れる前に一度deleteして、malloc後にfreeとなるのでしょうか。

また、読み書きに失敗した時に1回closeして再度接続処理をするというのは、通信失敗
した時に強制的にCloseするということなのでしょうか。
この通信失敗は、USBの接続断認識とは別物と考えて良いのでしょうか。

K 2015/09/29(火) 11:41:21
問題を整理した方がよさそうな気がしますが、
本題(?)の「メモリリーク」に関してのみ。

new / malloc() で確保したメモリを解放していないこのソースでは
メモリリークが発生するでしょう。
# thx > みいさん
なおここでのメモリリークはUSBもPICも関係ありません。
「確保したのを解放してない」単なる「C/C++の問題」です。

> InterfaceDataStructureの解放に関しては、WriteHandle7 = CreateFile((.....の下で
> deleteしましたが、

それだけではまだ不足しているでしょう。
たとえば MessageBox::Show(" 接続が切れました。", ...);
で return するケースでは、「delete しないまま」になってしまいます。
「すべての return 箇所」で delete する必要があります。

> DetailedInterfaceDataStructureの解放はどのようにすれば良いのでしょうか。
> Kさんが言うようにdeleteせずにmaloocで上書きしていますが・・・
> この場合は、最後のmalloc後でfreeすれば良いのでしょうか。もしくは、mallocで使わ
> れる前に一度deleteして、malloc後にfreeとなるのでしょうか。

new したものは delete して、malloc() したもの free() しなければなりません。

1)new する
2)delete する                   ←この処理が無いのでメモリリークしている
3)malloc() する
4)不要になったら free() する    ←この処理が無いのでメモリリークしている
の順番になるでしょうが・・・
このあたりの処理がすごく気持ち悪いので、私が手を入れるならざっくり
書き直します。

なべ使い 2015/09/29(火) 13:01:45
Kさんありがとうございます。

return箇所も全て、そうですよね。

Kさんみたくざっくり書き直すことは出来ないので、都度newに対してのdelete、
maloocに対してのfreeを追加してみます。

ITO 2015/10/02(金) 17:13:13
うーーん、
気になったのはKさんの
>後者の DetailedInterfaceDataStructure は、
>delete しないまま malloc() して上書きし、
こういうのまだないですか?

ひょっとしたらすべて、new-deleteで済ませられるのではないでしょうか。

なべ使い 2015/10/07(水) 21:15:43
ITOさんありがとうございます。

間を空けてしまいすみません。
return箇所も含めて行っておりますが、return箇所にdelete()を入れるとエラーが発生
するなどあり、ちょっと時間が掛っております。
エラーとしては、以下のようなものです。
・System.Runtime.InteropServices.SEHException'のハンドルされていない例外が
xxxxxx.exeで発生しました。
追加情報:外部コンポーネントが例外をスローしました。
・_Block_Type_Is_Valid (pHead->nBlockUse)
・_CrtIsValidHeapPointer(pUserData)

あと、この部分を解消すればメモリリークもなくなるので無いかと思っています。
思いたいです・・・

また、すみませんがご教示の程お願い致します。

みい 2015/10/08(木) 17:12:20
deleteした後にまたその変数をdeleteしているとかはないですか?

下記で二重delete防いではいかがでしょうか。
・deleteしたら変数にNULLをセットする
・delete前にNULLかどうかチェックして、NULLだったらdeleteする

ITO 2015/10/09(金) 15:37:06
deleteとnewの重複をチェックしたほうがいいですね。

void Connect_check( void )を抜けてところでdeleteしている可能性もありますね。

なべ使い 2015/10/11(日) 21:20:52
みいさん、ITOさんありがとうございます。
二重deleteでエラーが出ていました。やはり、deleteしたらNULLにて、NULLチェックもするよう
にします。
関数抜けてのdeleteはないみたいです。

長々とご教示頂いてありがとうございます。
本当に助かります。

また、宜しくお願い致します。

みい 2015/10/13(火) 13:57:14
多分ハンドルCloseの件解決していない気がします…

CreateとCloseのとこにBreakPointはって
1対1で対応しているか確認してみて下さい。

古いスレッドには追加発言できません。