4

私はCを学び始めています.C文字列ポインタと少し混乱しています.

int argc = 0;
const char *str[] = { "hello" , NULL, NULL };
str[argc++] = "nice!";
str[argc++] = "abc";
str[argc++] = "def"
send_args(argc, str); 
//the prototype/header : int send_args(int argc, const char **args);

send_args 関数は渡された str の値を変更しないため、それらの操作は有効ですか? 私は次のようなことをしたくないので:

int i, argc = 0;
char *str[3];
str[argc++] = strdup("nice!");
str[argc++] = strdup("abc");
str[argc++] = strduo("def)"
send_args(argc, str);
for (i = 0; i< argc; i++)
    if (str[i]) { free(str[i]); str[i]=NULL; }

よろしくお願いします。

4

5 に答える 5

4

最初の例には何の問題もありません。

于 2013-03-11T12:02:03.617 に答える
1

はい、大丈夫です。文字列リテラルは初期化されたデータセクションに配置される可能性が高く(詳細は実装で定義されます)、リテラルを解放する必要はありません(実際には可能性すらありません)。のタイプは、strで必要なタイプと互換性があるsend_argsため、すべて問題ありません。

str[]記述されているように、3つの要素で初期化されるため、4つ以上のポインターを保持できないことに注意してください。次のような宣言と初期化で同じ効果を達成できます。

const char *str[3];
str[0] = "nice!";
str[1] = "abc";
str[2] = "def"
send_args(3, str); 
于 2013-03-11T12:04:59.283 に答える
0

はい、それらは完全に有効です。argcただし、必要以上にインクリメントしているため、心配する必要があります。正しく扱っている限り、「望ましくない影響」を引き起こすことはありません。ここでコードの例を確認できます

于 2013-03-11T12:41:20.823 に答える
0

自動保存期間について質問している場合、str配列が作成されたブロックの最後に実行が到達するまで、配列は破棄されません。

const char **fubar(void)
{
    int argc = 0;
    const char *str[] = { "hello" , NULL, NULL }; /* str is created here */
    str[argc++] = "nice!";
    str[argc++] = "abc";
    str[argc++] = "def"
    send_args(argc, str); /* the lifetime of str is still valid here */
    return str; /* ... but str gets destroyed after this "return" statement */
}

int main(void) {
  const char **fubared = fubar();
  /* str has already been destroyed, and fubar's return value has been rendered garbage */
  /* so using fubared would be a bad idea. */
  return 0;
}

return実行が、それが作成されたブロックの終わりを超え、返されるポインターがガベージを指すため、 str が破棄されます。

于 2013-03-11T12:46:00.003 に答える
-1

この場合、文字列はコンパイル時に静的に格納され、解放できないため、それらは有効です。それらのポインターアドレスも、使用している関数に依存しません。

ただし、ローカルの char 配列を に使用する場合"nice!"、send_args は他の関数のローカル変数を読み取ることができないため、有効ではありません。

于 2013-03-11T12:06:29.100 に答える