0

このコードでは、入力ファイルからすべての文字を含むリストを作成しようとしています。主な問題は、「関数のローカル変数を返すことはできません」という文にあります。私をとても混乱させました。リストを動的に割り当てて返しましたが、動的割り当てなしで定義して返すことはできList listますか? すべての情報が自動的に削除され、私が作成した元のリストのアドレスだけが残るので、それは間違っていると思います。

詳細については、次のコードを参照してください。

typedef struct Item {
    char tav;
    struct Item* next;
} Item;

typedef struct List {
    Item* head;
} List;

List* create(char* path) {
    FILE* file;
    List* list;
    Item* trav;
    Item* curr;
    char c;

    file=fopen(path, "r");
    if (file==NULL) {
        printf("The file's not found");
        assert(0);
    }

    if (fscanf(file, "%c", &c)!=1) {
        printf("The file is empty");
        assert(0);
    }
    trav=(Item *)calloc(1, sizeof(Item));
    trav->tav=c;
    list=(List *)calloc(1, sizeof(List)); /* allocating dynamiclly the list so it won't be lost at the end of the function*/
    list->head=trav;

    while (fscanf(file, "%c", &c)==1) {
        curr=(Item*)calloc(1, sizeof(Item));
        curr->tav=c;
        trav->next=curr;
        trav=curr;
    }
    trav->next=NULL;

    fclose(file);

    return list;

}

私は正しいですか?これは必要ですか?それを返すポインタの代わりに List を定義できますか?

4

2 に答える 2

1

関数のローカル変数へのポインタを返すことはできません。{ローカル変数は、関数のscope( 、 )を超えて存在しません}
関数のローカル変数のアドレスを返すと、いわゆる未定義動作が得られます。

あなたは非常によく戻ることができます:

  • 値によるローカル変数または
  • 動的に割り当てられたメモリを指すポインタ

コピーを返すためにメモリが過剰に使用されることに本当に悩まされていない限り、最初の方をお勧めします。

動的割り当てなしでリストリストを定義して返すことはできますか?

はい、次の
条件があります。

List create(char* path); 
于 2012-09-17T11:29:57.403 に答える
1

関数のローカル変数を返すことはできません

この文は完全に間違っています。たとえば、この関数では次のようになります。

int f(void)
{
    int x = 5;
    return x;
}

ローカル変数を返す完全に有効な関数です。

知っておくべきことは、関数のローカル変数のアドレスを返すことはできない(または、返すべきではないと言う方がよい)ということです。これは、関数がアドレスを返すと、アドレスがガベージを指し、使用できなくなるためです。

あなたの例では、ローカルListを非常に安全に定義して返すことができます。

それでも動的に割り当てる必要があることに注意してください。つまり、上記と同じ理由で、タイプのローカル変数を取得してそれを指すtravことはできません。Itemlist->head

于 2012-09-17T11:30:38.770 に答える