0

すべての配列値に同じ値が含まれていると、ループ内の char 配列に値を割り当てることができません

たとえば、これは機能します

char* foo[3];

foo[0] = "mango"; foo[1] = "kiwi"; foo[2] = "banana";

int i=0; for(i=0;i<3;i++) 
{
   printf("%s\n",foo[i]); 
}

しかし、これはそうではなく、その理由がわかりません。

char* foo[3]; int i=0;

for(i=0;i<3;i++) {
  char temp[5];
  sprintf(temp,"VAL:%d",i);
  foo[i] = temp; 
}

for(i=0;i<3;i++) 
{
  printf("%s\n",foo[i]); 
}

助けてください、事前に感謝します

4

4 に答える 4

3

2 番目のスニペットの問題は、 のすべての要素がfoo同じ変数 を指していることですtemp。これは、2 番目のスニペットが実行されると範囲外になり、for未定義の動作になります。範囲外ではなかったとしても、すべての要素がfoo同じバッファを指していて、これは正しくありません。

修正するには、 のコピーを作成しtemp、 の各要素に保存する必要がありfooます。これはstrdup()、利用可能な場合 (ない場合malloc()strcpy())を使用して実現できます。

for (i = 0; i < sizeof(foo)/sizeof(foo[0]); i++)
{
    char temp[6];
    snprintf(temp, sizeof(temp), "VAL:%d", i);
    foo[i] = strdup(temp); /* Must be free()d later. */
}

またはタイプを変更します( unwindfooですでに提案されているように):

char foo[3][6];
int i;
for (i = 0; i < sizeof(foo)/sizeof(foo[0]);i++)
{
    snprintf(foo[i], sizeof(foo[i]), "VAL:%d", i);
}

その他の変更:

  • 文字によって追加された null ターミネータが必要なため、temptoのサイズが大きくなりました。このため、投稿されたコードにはバッファ オーバーランがあります。65VAL:%d sprintf()
  • を使用しsnprintf()てバッファ オーバーランを回避します。
  • 要素数をハードコーディングする代わりにsizeof(foo)/sizeof(foo[0])、配列内の要素数を計算するために を使用します。foo
于 2012-11-07T13:53:20.483 に答える
2

char*Cでは、aは実際には文字列を格納しませんが、文字列の最初の文字として扱われるメモリ位置のアドレスを格納することを覚えておく必要があります。

最初の例では、配列の各要素がfoo異なる文字列リテラルのアドレスを保持しています。2番目の例では、配列の各要素がfooローカル変数を指すように作成されていますtemp。ループを反復するたびに、の個別のインスタンスが生成されますがtemp、正常なコンパイラーは、これらすべてのインスタンスを相互に重ねて配置するため、経験する結果が得られます。

解決策は、2D配列を使用することです。

char foo[3][6]; int i=0;

for (i=0; i<3; i++) { sprintf(foo[i],"VAL:%d", i); }

for (i=0; i<3; i++) { printf("%s\n", foo[i]); }

または、動的割り当てを使用するには:

char* foo[3]; int i=0;

for (i=0; i<3; i++) { char* temp = malloc(6); sprintf(temp, "VAL:%d", i); foo[i] = temp; }

for (i=0; i<3; i++) { printf("%s\n", foo[i]); free(foo[i]); }
于 2012-11-07T14:04:54.920 に答える
0

ループ内のtemp変数は、おそらく各反復で同じメモリを再利用しているため、各foo[]スロットに同じアドレスを書き込むことになります。さらに悪いことに、ループを抜けるとそのアドレスにアクセスできなくなり、未定義の動作が発生します。

各文字列を動的に割り当てるか、実際の文字列 (char foo[3][20];または何か) 用のスペースを含む文字列配列を使用する必要があります。

于 2012-11-07T13:54:32.943 に答える
0

2 つの問題:

temp1) asを宣言しchar temp[5]、4 文字以上を詰め込んでいる:

sprintf(temp,"VAL:%d",i);

sprintf が配列の終わりを超えて書き込むようにすることで、終端を書き込む必要があります。\0

2) 変数tempは for ループに対してローカルであり、ループが終了すると範囲外になります。

于 2012-11-07T13:54:33.450 に答える