2009-07-31 24 views
3

私は文字配列にコマンドライン引数を渡すの二つの方法が見つかりました:AIXシステム上のIBM XLCコンパイラでコンパイルargv文字配列の割り当てを処理するにはどうすればよいですか?

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); 
} 

は[MyPrompt]>

を返し./a.out

S1:

S2 ./a.out:

./a.out

どの実装(s1またはs2)が正しいですか? argv [0]は任意の長さにすることができるので、s1はいいです。 s2では、argv [0] <の長さが256文字である必要があります。

s1がどのように動作するのかわかりません。私はだと思います。コンパイル時にs1の右側が必要ですが、は実行時に生成されると考えています()。

答えて

3

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

私は通常、引数変数からのみ読み込むべきであるので、最初のオプションを優先します。

+0

その場合、int mainの引数を(const int argc、const char ** argv)に変更しないでください。 – Pete

+0

あなたは移植性がない唯一の理由があります:それを受け入れないコンパイラがある可能性があります。 – quark

+5

constはC言語に新たに追加されたもので、main()は古代のC言語の子供時代に定義されて以来、const装飾はありません。 しかし、char *はconst char *に変換できるので、矛盾を心配する必要はありません。 –

3

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

文字列を変更したい場合は、その文字列をコピーできます。あなたのシステムがそれをサポートしているなら、より安全なstrnlen()とstrncpy()を使うべきです。

0

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

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

1

私はのコンパイル時に の右側が必要だと思うが、それは の実行時に生成されたと思う。

いいえ、ステートメントに遭遇するたびに必要です。例:

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

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

1

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

私は人々がargv [0]の値を変更するのを見ました。場合によっては(いくつかのOS上で)argv [0]を変更すると、あなたが変更したものとしてpsにプログラムが表示されます。

0

特にargv [n]がn> 0の場合、s1と一緒に行くでしょう。s2のようなものは古典的なバッファオーバーフロー攻撃のためにあなたを開きます。基本的に、ユーザーは長さが256文字を超える引数を書式設定し、スタック上の情報を上書きして、必要なコードを実行できるようにします。

関連する問題