1. ホーム
  2. c

argc はオーバーフローしますか?

2023-10-23 22:05:17

質問

SOの中をさまよっていたら この質問 . そして、私はargcをオーバーフローさせることができるかどうかを疑問に思うようになりました。

標準では argv[argc] はヌルポインタでなければならないとされていますが、argcがオーバーフローした場合、これは偽になります。

(I が書いた をテストするために小さな C プログラムと Python スクリプトを書きましたが、その結果 MemoryError .)

ありがとうございます。


<ブロッククオート

国際規格の根拠 - プログラミング言語 - C §5.1.2.2.1 プログラムの起動

の指定は argcargv を引数として main は、広範な先行実践を認識します。 argv[argc] は、リストの終わりに対する冗長なチェックを提供するために、ヌルポインタであることが要求されており、これも一般的な慣行に基づいています。

どのように解決するのですか?

規格によると

では、引用から。

argv[argc] はヌルポインタであることが必要です

そのため argc はオーバーフローすることはできません。

実際には

実際には、プログラムに渡される引数の合計サイズには制限があります。

私の Linux/x64 システムでは。

$ getconf ARG_MAX
2097152

したがって、引数の合計サイズは約2メガバイトとなり argc はオーバーフローすることができません。 この制限値は argv のデータの総量と、環境の組み合わせを測定していると思われます。 コマンドを実行しようとしたときに、この制限を超えると exec() で失敗します。 E2BIG . から man 2 execve :

E2BIG 環境 (envp) と引数リスト (argv) の合計バイト数が大きすぎます。
       リスト(argv)の総バイト数が大きすぎます。

私のシステムの ~2 メガバイトの制限は、他のシステムに比べて比較的寛大であると思います。 私の OS X システムは ~260KB の制限を報告しています。

しかし、次のような場合はどうでしょう。 ARG_MAX が本当に大きかったらどうでしょう?

さて、あなたが古い/奇妙なシステムを使っているとしましょう、それで int は 16 ビットで、ARG_MAX は 2 をはるかに超えています。 15 であり、それ以外は非常に合理的です。 さて、あなたが execve() を2つ以上の 15 の引数を取ることができます。 この実装には2つのオプションがあります。

  1. それは argc をオーバーフローさせることができます。基本的には、データを捨て、実行中のプログラムが予期しない、おそらくは誤った方法で実行されるようにし、C標準に違反することになります。 最悪なのは、このエラーは沈黙しているので、決して知ることができないかもしれないことです。

  2. あるいは、単に EOVERFLOW から execve() というエラーメッセージが表示され、 それほど多くのパラメータを持つイメージを実行することはできないことを通知します。 POSIX / SUS 標準はこのエラー結果について何も言及していませんが......これは単に標準作成者が ARG_MAX よりも大きくなることを想定していなかったからではないでしょうか。 INT_MAX .

オプション #2 は だけ であり、妥当な選択肢です。 システムが何らかの方法でオプション #1 を選択した場合、それは 壊れている であり、バグ レポートを提出する必要があります。

あるいは、16 ビット システム用にコンパイルされた古いプログラムを、ある種のエミュレーターまたは互換レイヤーを通して実行しようとしている可能性もあります。 エミュレーターまたは互換性レイヤーは、2 つ以上の 15 パラメータを渡そうとすると、エラー メッセージが表示されると思います。