質問

次のコードでは、私は非常に奇妙な結果を得ることができます。なぜ最後の要素の値は、以前のすべての配列要素を上書きしていますか?私はちょうどこの直ちに実行問題よりも大きな問題があると疑わます。

#include <stdio.h>

main()
{
    int i, cases;
    char num[1000000];

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        scanf("%s", &num);
        array[i] = &num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value) 
        printf("%d %p\n", i, &array[i]); //print (array index) (array address) 
    }
}

Inputs:
3 <-- number of lines to follow
0   <-- put in array[0]
1   <-- put in array[1]
2   <-- put in array[2]

Outputs
0 3         <-- why is this being overwritten with the last element?
0 0013BCD0
1 3         <-- why is this being overwritten with the last element?
1 0013BCD4
2 3
2 0013BCD8

正しい解決策はありません

他のヒント

あなたはarray[i] = &num;配列のアドレスにarray[i]要素の値を設定しているnum

ここでの結論は、ラインです。 arrayはchar配列であることから、私はそれがあなたのnumのアレイアドレスを切り捨てだ疑いがある、と下位バイトはわずか3であることを起こるます。

しかし。いえ、あなたのchar NUM [1000000]は恐ろしい形で、あなたはすべてで、それを行うべきではありません。天国のために、ヒープ上に割り当て、そして小さな数を選択します。また、scanf関数(「%sの」、&numが)実際に何をしたいあなたを与えることはありません。ここにヒントがあります。数字を読み取ることGETC()ループを使用します。これは)(scanfのための配列の任意の事前割当てを実行する必要が回避される。

あなたは、配列のすべてのインデックスに同じアドレス(char型のNUM [1000000]のアドレスを;)入れているためです。

これは、ダイナミックアロケーション(のcalloc、malloc関数、新しい、など)にあなたを導くでしょうエラーです。

乾杯!

num個の配列の異なる要素に各入力を書く

は、あなたの最初のループの中に、あなたがする必要があります(しかし、あなたはそうではありません)。代わりに、あなたは常に、すなわち&numに、同じ場所に書いている。

のchar *配列[ケース];

これはコンパイル時に割り当てられ、実行時ではありません。 (私はあなたがそれがとにかく動的に仕事をしたいと思いますが。)及び例は初期化されていないので、あなたはメモリを事前に割り当てる必要がある、またはライブラリ関数のmalloc関数ファミリに慣れるのいずれか。

置き換え

//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", &num);
    array[i] = &num;
}

タグ付き
array[0] = num;
//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", array[i]);
    array[i+1] = array[i] + strlen(array[i]) + 1;
}

num[]における最初の利用可能なスペースに各文字列をスキャンし、次の利用可能なスペースを指すようにarray[]の次の要素を設定します。さて、文字列のあなたのprintf()は動作します。元はnum[]の開始にすべての文字列をスキャンしました。

注:それは丸呑みされるデータの量に制限をかけていないので、飾り気のないscanf()%sは、gets()と同じくらい悪いです実際のコードでは使用しないでください。

。。

置き換え

    printf("%d %p\n", i, &array[i]); //print (array index) (array address) 

タグ付き
    printf("%d %p\n", i, (void*)(array[i])); //print (array index) (array address) 

実際むしろa[]の要素のアドレスより、a[]に格納されたアドレスを印刷します。あなたがものを提供しなければならないので、%pがポインタ-tovoidを期待しているため、キャストが必要になります。

ザッツ固定されているあなたのコード:

#include <stdio.h>

main(void)
{
    int i, cases;

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        char *num = malloc(100000);
        scanf("%s", num);
        array[i] = num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value)
        printf("%d %p\n", i, (void*)&array[i]); //print (array index) (array address)
    }
    return 1;
}

あなたが同様に使用することができます。

char *num = calloc(100000, sizeof(char));

少し守備のです。あなたはあなたがmalloc関数を使用して動的にそれを行うことができます100000を必要とする理由私は知りません。これは多くの作業を必要とするが、非常に堅牢であるだろう。

どのようなあなたのコード内でhapenningされることは、あなたが、あなたはそのアドレスに配列[i]の要素を割り当て、変更されませんNUMのアドレスに文字列%sのを保存することです。 Cに割り当てておくと、その後の参照を保存する他には何もありません、あなたは、スペースの無駄になり、このitself-要素を格納しません。したがってその参照がありません(あなたがあなたの記事で述べたようにない3)それらはすべて2に変化しているなぜ配列要素のすべてが(参照のみを保存)アドレスを指すように、住所変更の値は、それはです。

これは、C ++がなされているように見えるようなもののためです。ユーザ入力解析および動的割り当ては、より確実に行われ、風にされています。 私はあなたがC ++に切り替えることができなかったユーザーインターフェース、のようなものを持っているシステムを考えることはできません。

もちろん、これは問題に苦しんでいる他のコードからのみの試験の抜粋である場合には、当然の...

<時間>

あなたのコードは、最近そのように行うべきではありませんCの初心者や物事のためのいくつかの一般的なミスに苦しんでます。

私が正しく理解していれば、あなたはserevalユーザー入力文字列を保存したい

(あなたは数字のみを表示するので、あなたの例の出力は、少し誤解を招くおそれがあり)ます。

あなたは(カウント例)文字列へのポインタをすべてを格納する配列を準備していますが、あなただけの1つの文字列のためのメモリを確保しています。あなたは、すべての文字列のためにそれを行う場合ようにする必要があります。 「動的なメモリ割り当て」レッスンの観点で物事をシンプルに保つために、私はそれをそのように行うことをお勧めします。char* array[cases][10000];あなたの10K文字の例文字列を与えます。

あなたはおそらく、あなたの配列要素に別々のポインタを持っている必要はありません。これは、あなたがそれらの要素は、ポインタ自体よりも大きい配列の要素をソートしたい場合は意味をなすために開始します。その場合には、パフォーマンスのあなたのゲインは、移動(コピー)大きなチャンクを持つことではなく、ポインタのみ(通常は4バイト)。あなたのケースでは、int型はまた、4バイト長です。そして、あなたはとにかくソートしません。)

scanf()は、控えめに言っても、危険です。 2番目のアプリケーションでは、配列のアドレスに文字列を書き込むためにそれを指示しています。これは単純なミスのようですが、多くの問題につながることができます。 scanf("%d", &array[i]);(残念ながら、私は手元にコンパイラを持っていないので、私は100%を確認していない):あなたはおそらくそのようにやりたいです。次の行をドロップします。)

<時間>

専門家を値下げする質問:なぜそれはCODE-ブロックと組み合わせたリストを持っているので、気に不可能である。

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