• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:SNMPマネージャAPIでメモリリークしてしまう)

SNMPマネージャAPIでメモリリークする

このQ&Aのポイント
  • ネットワークに接続したプリンタをSNMPで状態監視するソフトを作成していますが、SnmpMgrRequest()関数内でメモリリークが発生します。
  • この関数はエラーを返さず、1台のプリンタを監視するとメモリリークしないため、問題が何か分かりません。
  • 開発環境はWindowsXP(SP1) VC++6 SP5を使用しています。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

Musaffah様 Musaffah様は、WinSNMPを使用していないので、 SnmpCleanupは必要ありません。不適切なアドバイスをしてしまい、 申し訳ございませんでした。 サンプルコードありがとうございました。 さっそく、こちらでも確かめてみましたが、 メモリーリークも起きませんし、ちゃんと動作しているようです。 環境は、以下のとおりです。 Windows2000(SP4) VC++6.0(SP6) .NET2003 ダイアログベースのプロジェクトで、ボタンを押すと、 PrnStsGet関数を永久ループで呼び出すようにしました。 VC++6.0, .NET2003両方とも、問題なく動作しますし、 プリンターを2台モニターしても、問題ありません。 ということで、OSとVC++の最新アップデートをお勧めします。 VC++は、Service Pack6を、WindowsXPはSP2にアップデートした 上で、WindowsUpdateを実行して、最新にしたほうがいいでしょう。 会社の同僚で、ネットワーク通信プログラムがフリーズするという 問題が起きていたのですが、SP2にアップデートしたら、解決したようです。 もし、これでも、解決しないようであれば、 新規にテスト用プロジェクトを作成し、このプログラムだけを 実装して、動作テストをすることをお勧めします。 このことにより、問題の切り分けがはっきりするかもしれません。

Musaffah
質問者

お礼

お礼の返事が遅くなって申し訳ありません。 WindowsXPをSP2にアップデートしたところ、確かにメモリリークしなくなったことを確認しました! 大変助かりました。ありがとうございました!!

その他の回答 (1)

回答No.1

Musaffah様 WinSNMP APIについては、サンプルコードもないし、 google検索でも、ほどんど引っかからないので、 似たような例は見つかりにくいかもしれませんね。 さて、質問内容についてですが、コメントアウトされた ソースコードでは、こちらも、検証できないので、 自信はありませんが、以下を試してみてはいかがでしょうか? ●SnmpMgrStrToOid関数のあとに、SnmpUtilOidFreeでメモリを開放する。 ●SnmpMgrClose()のあとに、SnmpCleanup()を実行する。 > SnmpMgrRequest()関数内でメモリリークを起こします。 Microsoftが提供したAPIの場合、使い方を誤ると、たまに、 このようなことがおきます。 たとえば、マルチスレッドアプリケーションにおいて、 あるスレッドで初期化したインスタンスやサービスを 別のスレッドが使った場合などに発生したりします。

Musaffah
質問者

補足

woody_poco様。 アドバイスありがとうございます! SnmpCleanup()を実行したら2回目以降のチェックができなくなってしまいました(泣)。 質問でコメントアウトした関数を提示します(文字制限オーバーですが・・・すいません)。 SnmpMgrOpen()とSnmpMgeRequest()の初回実行時にのみそれぞれスレッドが1つずつ生成されているのまでは判明しましたが、メモリリークの原因は未だ不明です。 申し訳ありませんがご協力お願い致します。 #define ERR 0x0800 #define Bind RFC1157VarBind #define BindList RFC1157VarBindList #define AsnObj AsnObjectIdentifier int PrnStsGet(LPSTR adr){ UINT iRet=ERR; LPSTR oid=".1.3.6.1.2.1.25.3.5.1.2.1", comname="public"; LPSTR agt,cmnty; BindList bind; Bind *tmpVb; AsnObj obj; LPSNMP_MGR_SESSION se; BYTE req=SNMP_PDU_GET; AsnInteger errSts,errIdx; agt=(LPSTR)SnmpUtilMemAlloc((UINT)(strlen(adr)+1)); strcpy(agt,adr); cmnty=(LPSTR)SnmpUtilMemAlloc((UINT)(strlen(comname)+1)); strcpy(cmnty,comname); bind.list=NULL; bind.len=0; SnmpMgrStrToOid(oid,&obj); bind.len++; tmpVb=(Bind *)SnmpUtilMemReAlloc(bind.list,(sizeof(Bind)* bind.len)); bind.list=tmpVb; bind.list[bind.len-1].name=obj; bind.list[bind.len-1].value.asnType=ASN_NULL; se=SnmpMgrOpen(agt,cmnty,100,1); if(SnmpMgrRequest(se,req,& bind,&errSts,&errIdx)) if(errSts==0){ AsnAny *pAny=& bind.list[0].value; iRet = pAny->asnValue.address.stream[0]; } SnmpUtilVarBindListFree(&bind); SnmpUtilMemFree(agt); SnmpUtilMemFree(cmnty); SnmpMgrClose(se); return iRet; }

関連するQ&A