0

返されたリストがNULLである理由がわかりません。これはコードです:

私のList.hで

struct nodo_ {
    char* dato;

    struct nodo_ *next;
};
struct nodo_ *Lista;
/*Def list */
void createList(struct nodo_ **Lista);

私のmain.cで

struct nodo_ *Lista;

int main(){
    createList(Lista);
    while(Lista != NULL){        
         printf("The date is %s\n  ",Lista->dato); //Error here now
         Lisa = Lista->next;
    }

    return 0 ;
}

私の List.c im で List を作成します。

void createList(struct nodo_ *Lista){
    struct nodo_ *Aux_List = list_D;
    aux_List = malloc(sizeof(struct nodo_));

    char* path_a = "Hello"; 
    char* path_B = "Minasan";

    /* Store */
    aux_List->dato = path_a;
    aux_List = Aux_List->next;    
    aux_List = malloc(sizeof(struct nodo_));
    aux_List->dato = path_b;
    aux_List->next = NULL;

}

ありがとう。

4

2 に答える 2

3

そのポインタは値で渡されます。つまり、コピーが作成されます。ポインタを完全に新しい値に初期化したい場合は、別のレベルの間接化 (つまり a nodo_**) を使用する必要があります。

ちなみに、typedefポインタ型を ing することは、型が本当に不透明でない限り、ほとんどの場合悪い考えです (あなたのものではありません)。この「ルール」の理由の 1 つは、コード内の別のバグを考慮すると明らかです。

auxList = (Lista*)malloc(sizeof(Lista));

へのポインターにスペースを割り当てていますが、オブジェクトnoda_には十分ではありません。また、 C では の戻り値をキャストしないでください。 aはnoda_安全かつ暗黙的に他のポインター型に変換されるため、 冗長です。エラー。(C89 またはそれ以前のバージョンを実装するコンパイラにのみ適用されます)mallocvoid*stdlib.hmallocint

編集:

関数内でポインタ引数を初期化するには:

void init(struct node **n) {
    if(n)
        *n = malloc(sizeof(struct node));
}

int main() {
    struct node *n;
    init(&n);
}
于 2012-08-11T21:01:27.930 に答える
1

コードを掘り下げる前に、実際の質問に対する短い答え:

... 返されるリストが NULL である理由 ...

返されるリストはありません。結果を渡すために使用たりreturn、out パラメーターの値を設定したりしません。

編集したコードで:

void createList(struct nodo_ **Lista){
    struct nodo_ *Aux_List = list_D;
    aux_List = malloc(sizeof(struct nodo_));

最初Aux_Listに の現在の値に設定しますがLista、これはまだ初期化されていないことがわかっています。これは、初期化しようとしているからです。次に、その値を破棄aux_Listし、 によって返された新しいアドレスで上書きしますmalloc。には何も保存しません*Lista。これが、この関数が宣言どおりに機能する唯一の方法です。


Ed が示唆しているように、typedef には多くの有用な情報が隠されているので、展開してみましょう

struct nodo {
    char* dato;

    struct nodo *next;
};

/*Def list */
void createList(struct nodo* list_D);

これで、これが間違っていることがわかります。createListリストのヘッド ノードを渡すことはできますが (これはとにかく使用しません)、新しく割り当てられたリストを呼び出し元に返す方法はありません。

率直に言って、createListとにかく有用なプリミティブではないため、最初に賢明な基盤から始めます。

struct nodo *alloc_nodo(char *dato, struct nodo *next)
{
    struct nodo *n = malloc(sizeof(*n));
    n->dato = dato;
    n->next = next;
    return n;
}

さて、これを使って書き直す前に、今createList何をするか見てみましょう:

void createList(struct nodo *list_D)
{
    struct nodo *aux_List = list_D;
    aux_List = malloc(sizeof(struct nodo_));
    /* ^ so, we take the input argument and immediately discard it */

    char* path_a = "Hello"; 
    char* path_B = "Minasan";

    /* Store */
    aux_List->dato = path_a;
    aux_List = Aux_List->next;
    /* ^ note that we haven't initialized aux_List->next yet,
       so this is a random pointer value */

    aux_List = malloc(sizeof(struct nodo_));
    /* again, we set aux_List to something,
       but immediately overwrite and discard it */

    aux_List->dato = path_b;
    aux_List->next = NULL;
}

そのため、入力を無視し、出力を返さず、互いに接続されていない部分的に初期化された 2 つのノードをリークします。私はあなたがこのような何かをもっと達成したかったと信じています:

struct nodo* create_my_list()
{
    struct nodo *tail = alloc_nodo("Minasan", NULL);
    /* the end (tail) of the linked list has a NULL next pointer */

    struct nodo *head = alloc_nodo("Hello", tail);
    /* the head of the linked list points to the next node */

    return head;
    /* like a snake, you hold a singly-linked list by the head */
}

この関数を使用するように記述mainすると、次のようになります。

int main()
{
    struct nodo *head = create_my_list();
    struct nodo *n;
    for (n = head; n != NULL; n = n->next)
    {
         printf("The date is %s\n  ", n->dato);
    }
}
于 2012-08-11T21:42:08.197 に答える