链接列表在C中为空

时间:2012-08-11 20:58:16

标签: c linked-list

我不知道为什么返回的列表是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中创建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;

}

感谢。

2 个答案:

答案 0 :(得分:3)

该指针正在按值传递,即复制。如果您希望将指针初始化为一个全新的值,那么您必须使用另一个间接级别(即nodo_**)。

另一方面,typedef指针类型几乎总是一个坏主意,除非该类型真的是不透明的(你的类型不是)。当您考虑代码中的另一个错误时,这个“规则”的一个原因很明显:

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

您为指向noda_的指针分配空间,对于noda_对象来说还不够。此外,不要在C中强制转换malloc。这是多余的,因为void*被安全地隐式转换为任何其他指针类型,如果您忘记包含stdlib.hmalloc将被假定为返回int的函数,并且演员隐藏错误。 (仅适用于实现C89或旧版本的编译器)

编辑:

初始化函数中的指针参数:

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

int main() {
    struct node *n;
    init(&n);
}

答案 1 :(得分: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;
}

因此,它忽略其输入,不返回任何输出,并泄漏两个未相互连接的部分初始化节点。我相信你想要达到更像这样的东西:

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);
    }
}