argv文字配列の割り当てを処理するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1214251

  •  06-07-2019
  •  | 
  •  

質問

コマンドライン引数を文字配列に渡す2つの方法を見つけました:

int main (int argc, char **argv)
{
  const char *s1 = argv[0];
  char s2[256];
  strcpy(s2, argv[0]);

  printf("s1: %s\ns2: %s\n\n", s1, s2);
}

AIXシステム上のIBM xlcコンパイラーでコンパイル

  

[MyPrompt] <!> gt; ./a.out

     

s1:./a.out

     

s2:./a.out

どの実装(s1またはs2)が正しいですか? argv [0]は任意の長さにできるため、s1は便利です。 s2では、argv [0] <!> lt;の長さが必要です。 256文字。

s1の動作方法/理由を理解できません。コンパイル時にはs1の右側を考える必要がありますが、実行時に生成される考える

役に立ちましたか?

解決

s1が機能する理由は、argv [0]のタイプが ポインターであるためです。単にアドレスを割り当てているだけで(実際の値ではなく)、安全です。いかなる種類の割り当てやキャストも実行していません。

通常、最初のオプションを好むのは、引数変数からのみ読み取る必要があるためです。

他のヒント

文字列を変更したくない場合は、s1が機能します。

文字列を変更する場合は、そのコピーを作成できます。システムでサポートされている場合でも、より安全なstrnlen()およびstrncpy()を使用する必要があります。

  

s1の右側を考える   コンパイル時に必要になるはずです。   しかし、私はそれがで生成されると思います   実行時。

いいえ、ステートメントが検出されるたびに必要です。例:

void f() {
   int x = 1;
   ...
}

整数xは、コンパイル時ではなく、関数が呼び出されるたびに1に初期化されます。

s2には、バッファーオーバーランの影響を受けやすいという優れた特性があります。

人々がargv [0]の値を変更するのを見てきました。場合によっては、(一部のOSでは)argv [0]を変更すると、変更したものとしてプログラムがpsに表示されます。

引数を変更せずに参照する場合は、 s1 が正しいです。

引数を何らかの方法で変更する必要がある場合は、 s2 の例のように引数のコピーを作成する必要がありますが、 s2 の例では、長さがコピー先のバッファより長いかどうかを確認します。たとえば、入力としてfilename.jpgのような引数を取り、出力としてfilename.gifを保存する場合、拡張子を.jpgから.gifに変更するため、その引数のコピーを作成する必要があります

特にargv [n]の場合、n <!> gt;でs1を使用します。 0. s2のようなものは、古典的なバッファオーバーフロー攻撃の可能性を開きます。基本的に、ユーザーは長さが256文字を超える引数をフォーマットし、スタック上の情報を上書きして、必要なコードを実行できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top