初めて投稿します。
ネットワークに接続したプリンタ4台を、SNMPを使って状態監視するソフトを作成しています。以下のソース(文字数制限のため、大半をコメントで記述しています)を実行すると、SnmpMgrRequest()関数内でメモリリークを起こします。
この関数の戻り値はエラーではありません。しかもプリンタ1台のみを監視するとメモリリークしません。この関数をコメント化しても起きません。
SNMPは始めてなので何が悪いのかよくわかりません。
どなたか何かご存知であればご教示お願いします。
開発環境はWindowsXP(SP1) VC++6 SP5を使用しています。
(ソースの拡張子は.cです。)
void main(){
while(1){
for (i = 0 ; i < 4 ; i++) {
mib=StsGet([プリンタのIPアドレス]);
}
Sleep(600);
}
}
int StsGet(LPSTR adr) {
//SnmpUtilMemAlloc ()でSNMPエージェントのアドレス取得
//SnmpUtilMemAlloc()でコミュニティ取得
//変数バインディングの初期化
//SnmpMgrStrToOid()でOIDを文字列から値に変換
//SnmpUtilMemReAlloc ()で変数バインディングにメモリを割当て
//変数バインディングにOIDを追加
//SnmpMgrOpen ()でSNMPマネージャAPIのオープン(タイムアウト:100ms、リトライ:1回)
// SnmpMgrRequest()でSNMPマネージャAPIに指定操作(Get)を要求
//SnmpUtilVarBindListFree(),SnmpUtilMemFree()で各変数を解放
//SnmpMgrClose()でSNMPマネージャAPIとの接続を終了
return [プリンタ状態;]
}
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にアップデートしたら、解決したようです。
もし、これでも、解決しないようであれば、
新規にテスト用プロジェクトを作成し、このプログラムだけを
実装して、動作テストをすることをお勧めします。
このことにより、問題の切り分けがはっきりするかもしれません。
お礼の返事が遅くなって申し訳ありません。
WindowsXPをSP2にアップデートしたところ、確かにメモリリークしなくなったことを確認しました!
大変助かりました。ありがとうございました!!
No.1
- 回答日時:
Musaffah様
WinSNMP APIについては、サンプルコードもないし、
google検索でも、ほどんど引っかからないので、
似たような例は見つかりにくいかもしれませんね。
さて、質問内容についてですが、コメントアウトされた
ソースコードでは、こちらも、検証できないので、
自信はありませんが、以下を試してみてはいかがでしょうか?
●SnmpMgrStrToOid関数のあとに、SnmpUtilOidFreeでメモリを開放する。
●SnmpMgrClose()のあとに、SnmpCleanup()を実行する。
> SnmpMgrRequest()関数内でメモリリークを起こします。
Microsoftが提供したAPIの場合、使い方を誤ると、たまに、
このようなことがおきます。
たとえば、マルチスレッドアプリケーションにおいて、
あるスレッドで初期化したインスタンスやサービスを
別のスレッドが使った場合などに発生したりします。
この回答への補足
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が見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- UNIX・Linux Zabbix監視エージェントをインストールしてもデータを収集できずアクティブにならない 1 2023/02/26 20:25
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- システム CSVファイルのマッピング処理の省力化 1 2022/11/24 00:01
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- その他(コンピューター・テクノロジー) 【Tableau Desktop】文字列から8桁の数字を日付型(yyyyMMdd)として取得 1 2023/07/31 10:17
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
- C言語・C++・C# C言語 3 2022/10/04 15:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Macターミナルで実行中のプログ...
-
実行時エラー429
-
VB上で実行中の無限ループの止め方
-
C言語でフォルダを開く
-
SNMPマネージャAPIでメモリリー...
-
プリントスクリーンをプログラ...
-
clock関数は正確じゃないの?
-
C言語で途中までしか、プログラ...
-
vba GetAsyncKeyState関数について
-
プロセス間通信について
-
fortranで長いプログラムを書き...
-
並列計算をしたときのシステム...
-
C言語でプログラムを再起動
-
アクセス[ファイルを開かずに、...
-
一定時間たつと、リセットしたい
-
vbsで同一ファイルに出力するには
-
system関数を使用してsuコマン...
-
逆コンパイルと逆アセンブルの...
-
緯度、経度の 10進法と 60進法...
-
イラストレーターCS4のシリアル...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Macターミナルで実行中のプログ...
-
sendkeysにてALT+CTRL+INSERTを...
-
他のPC上にあるexeを、そのP...
-
実行時エラー429
-
system関数を使用してsuコマン...
-
プログラミング ソースコード
-
C言語で途中までしか、プログラ...
-
MACで動く実行ファイルをWindow...
-
clock関数は正確じゃないの?
-
あるプログラム実行中に別のプ...
-
VBAで外部プログラムを非表示で...
-
並列計算をしたときのシステム...
-
システム資源とは?
-
C言語でフォルダを開く
-
終了してもプログラムが実行し...
-
Windows10でDOSゲーム
-
なんかC言語でプログラム書いて...
-
プロセス間通信について
-
プログラムを走らせる
-
RPG パラメーターについて
おすすめ情報