Help us understand the problem. What is going on with this article?

poptについて

More than 3 years have passed since last update.
  • 個人的な備忘録ですので、詳しいところと詳しくないところがアンバランスかも
  • ただし誤りの指摘は歓迎します

ライセンス

  • 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

Why not register and get more from Qiita?
  1. 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
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away