More than 3 years have passed since last update.
- 個人的な備忘録ですので、詳しいところと詳しくないところがアンバランスかも
- ただし誤りの指摘は歓迎します
ライセンス
バージョン
使い方
オプション指定
struct poptOption optionTable[]={}
- 要素は、
{"long-name", 'short_name', arg_type(数値), arg(参照値), 識別子(数値), "説明1(--option[=__ここに入る__])", "説明2"}
- たとえば、arg_typeを
POPT_ARG_INT
にするなら、argはint*
。
- POPT_ARG_NONEの場合、*argに1が代入される。
- POPT_ARG_VALの場合、*argに識別子が代入される。
- POPT_ARG_STRINGの場合、*argにオプション値が代入されるが、popt 1.16では複製、開発版では移動が発生する。
- 前者の複製されたメモリの元側は、後のオプションの有無で解放されたりされなかったりする
流れ
-
poptGetContext()
でコンテキスト取得
-
poptGetNextArg()
を回す
- POPT_ARG_VAL以外のタイプで識別子を設定した場合は、途中でその識別子が帰ってくることがある
-
poptGetOptArg()
でオプション値を取得した上で、細かい設定ができる
- POPT_ARGFLAG_OPTIONALの場合、オプション値がNULLの場合があるが、その値の設定もここで行う
- オプション値がない場合1にするとかはデフォルトではやってくれない
-
poptGetOptArg()
の返し値は文字列
-
poptFreeContext()
で解放
メモリリーク
その1
- オプション値に相当する部分のメモリが開放されないため、たとえば、
{"option",'o',POPT_ARG_INT|POPT_ARG_OPTIONAL,&flg,OPT_O,NULL,NULL}
のとき、-o2
と付けるだけで2\0
に相当する2バイトがリークする。
- この問題は最新版であるbzr r789では改善されている。
- ただし、arg(参照値)を指定している場合、GetOptArg()ではNULLが帰ってくる。
for(;(optc=poptGetNextOpt(optCon))>=0;){
if(optc==OPT_O){
char *arg=poptGetOptArg(optCon);
if(arg)flg=strtol(arg,NULL,10);
else flg=1;
}
}
- というコードは、
- flgに2を代入した後当該文字列は開放される
-
poptGetOptArg()
でNULLが帰ってくる
- 結果、flgに意図せず1が代入されてしまう
- ため、禁則である。
- 結果、POPT_ARG_OPTIONALを指定する場合、argはNULLにする必要があるといえる。
- OPTIONALでない場合は、argの中身を見て処理をするだけということも可能なので、NULLにしない場合もある。
- 1.16以下ではflgには正常に2が代入されていた(勿論メモリリークのせい)。
その2
- その1でメモリが開放されるのは、
- (
poptGetOptArg()
によらない)flgへの代入が発生した時
-
poptGetOptArg()
を呼ばずにpoptGetNextOpt() または poptFreeContext()
を呼んだ時
- である。したがって、poptGetOptArg()により得られたメモリは自分で解放しなければならない。
- poptGetOptArg()により、メモリがpoptの管理外になるためである。同様に、POPT_ARG_STRINGについても、参照値に割り振られたメモリはpoptの管理外になるため、自分で解放しなければならない。
rsync
Why not register and get more from Qiita?
- We will deliver articles that match you
By following users and tags, you can catch up information on technical fields that you are interested in as a whole
- you can read useful information later efficiently
By "stocking" the articles you like, you can search right away
Sign upLogin