繁体   English   中英

C中的链接列表为空

[英]Linked List Null in C

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

}

谢谢。

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

在一个侧面说明, typedef荷兰国际集团指针类型几乎总是一个坏主意,除非该类型是真正的不透明(这你是不是)。 当您考虑代码中的另一个错误时,很明显会出现此“规则”的原因:

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

您正在为指向noda_的指针分配空间,不足以容纳noda_对象。 另外,不要在C中malloc的返回值。这是多余的,因为void*已安全且隐式地转换为任何其他指针类型,并且,如果您忘记包含stdlib.h ,则将malloc假定为一个函数返回int ,并且强制转换隐藏错误。 (仅适用于实现C89或更早版本的编译器)

编辑:

要在函数内初始化指针参数:

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

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

在深入研究代码之前,请回答您的实际问题:

...为什么返回的列表为NULL ...

没有返回的列表,你既不用return传的结果,也不能设置输出参数的值。

在您编辑的代码中:

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

首先,将Aux_List设置为Lista当前值 ,您知道该尚未初始化,因为您正在尝试对其进行初始化。 然后,您丢弃该值,使用malloc返回的新地址覆盖aux_List 您永远不会将任何内容存储到*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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM