0

この構造の定義では:

struct word {
    char *cont; //content of the word
    char *wsp; //whitespace following the word
    int ctr;
};

一言で言えば、私はstdinから最初の単語を取得し、それに続くすべての空白を含む関数を作成しようとしています。ここにあります:

struct word *getword(){
    char cont[WORDLIM];
    char wsp[WORDLIM];
    cont[0] = '\0';
    wsp[0] = '\0';
    if (peekchar() == EOF) return NULL; //peekchar defined elsewhere as getting a char and ungetc-ing it

    REPEAT{ //macro for for(;;)
            char c = getchar();
            char buf[2];
            buf[0]=c;
            buf[1]='\0';
            if (c == '\n' || c == ' '){
                    strcat(wsp, buf);
                    if (peekchar() != '\n' && peekchar() != ' '){
                            struct word *toret;
                            toret = malloc(sizeof(struct word));
                            toret->cont = cont;
                            toret->wsp = wsp;
                            toret->ctr = -1;
                            printf("---%s---\n", toret->wsp); //just for debugging
                            return toret;
                    }
                    continue;
            }
    }
    printf("PANIC PANIC PANIC THIS IS GOING WROOOOONG!!!!!\n");
    return NULL;
}

楽しいのは、デバッグ行のためだけに空白の正しい出力を取得できることですが、getword()-> wspにアクセスしようとすると、ランダムなガベージが発生します。さらに興味深いことに、getword()->contは機能します...

私はCの本当に初心者です...私は何を間違えましたか?

4

3 に答える 3

4

スコープ外になったメモリへのポインタを返しています。

を動的に割り当てますstruct wordが、実際の文字はwsp配列に保持されます。関数が戻ると、それは範囲外なので、何かが含まれている可能性があります。

于 2013-01-29T19:44:33.660 に答える
3
REPEAT{ //macro for for(;;)

急いでそのマクロを失います。プリプロセッサを使用してC構文を非醜くすることは、胸焼けのレシピです。for(;;)またはを使用するだけwhile(1)です。コンパイラは通常、無条件のジャンプに変えるのに十分賢いです。

あなたの問題に関して:

toret->cont = cont;
toret->wsp = wsp;

および配列は、関数に対してローカルcontで宣言されます。関数が終了すると、配列は存在しなくなり、それらへのポインターは無効になります。あなたがする必要があるのは、それ自体のメモリに加えて、とのメンバーにメモリを割り当てることです。 wspgetwordcontwsptorettoret

toret = malloc(sizeof(struct word));
if (toret) // ALWAYS check the result of a `malloc` call
{
  toret->cont = malloc(strlen(cont) + 1);
  if (toret->cont)
    strcpy(toret->cont, cont);
  toret->wsp = malloc(strlen(wsp) + 1);
  if (toret->wsp)
    strcpy(toret->wsp, wsp);
  ...
}

cont構造体のメモリを解放する必要がある場合は、最初にとwspメンバーのメモリを解放する必要があることに注意してください。

于 2013-01-29T19:50:13.847 に答える
1

*toretあなたのプログラムのここにぶら下がっているポインタです

于 2013-01-29T19:46:25.903 に答える