LoginSignup
0
0

More than 5 years have passed since last update.

poptについて

Last updated at Posted at 2016-08-24
  • 個人的な備忘録ですので、詳しいところと詳しくないところがアンバランスかも
  • ただし誤りの指摘は歓迎します

ライセンス

  • X11 License(割と重要)

バージョン

使い方

オプション指定

  • 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に識別子が代入される。
    • この2つにはオプション値は付けてはならない。
  • 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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0