2016-08-01 58 views
-3

我正在处理单个链表并且无法解决问题(我认为问题是在添加函数时使用NULL指针),问题是它只添加第一个数字来列表并跳过休息呼叫添加功能。无法理解c中的空指针

#include<stdlib.h> 
#include<stdio.h> 

struct node 
{ 
    int i; 
    struct node* next; 
}; 

struct node* head = NULL; 

int add(int val) 
{ 
    if(head == NULL) 
    { 
    head = (struct node*)malloc(sizeof(struct node)); 
    head->i = val; 
    } 
    else 
    { 
    struct node* current = head; 
    while(current != NULL) 
    { 
     current = current->next; 
    } 
    current = (struct node*)malloc(sizeof(struct node)); 
    current->i = val; 
    } 
} 

int print(struct node* first) 
{ 
    while(first != NULL) 
    { 
    printf("%d\n",first->i); 
    first = first->next; 
    } 
} 

int main() 
{ 
    add(36); 
    add(46); 
    add(97); 
    print(head); 
    return 0; 
} 
+1

@underscore_d这就是所谓的C++,如果你想试着阻止人们询问关联链表的问题,那么这就是无关紧要的。 – immibis

回答

2

这里有两个问题。首先,在创建新节点时,不要将next设置为NULL。所以当你遍历列表时,你最终会读取垃圾数据,调用undefined behavior

然后接下来的问题是,当你遍历一个非空列表时,你从列表的末尾“脱落”,所以current在循环结束时为NULL,并且没有链接到列表的末尾。当current->next为空时,您需要停止,然后在那里创建新节点。

void add(int val)  // change return type to void since nothing is being returned 
{ 
    if(head == NULL) 
    { 
    head = malloc(sizeof(struct node)); // don't cast return value of malloc 
    head->i = val; 
    head->next = NULL;     // terminate list 
    } 
    else 
    { 
    struct node* current = head; 
    while(current->next != NULL)   // loop until you're on the last node 
    { 
     current = current->next; 
    } 
    current->next = malloc(sizeof(struct node)); 
    current->next->i = val; 
    current->next->next = NULL;   // terminate list 
    } 
} 
+0

我认为未初始化的指针与c中的NULL指针相同,这帮助我清除了疑问。 –

+0

@neeraj_nigam还有一个选项可以用'calloc'初始化每个节点。有关更多信息,请参阅[这里](http://en.cppreference.com/w/c/memory/calloc)。调用语法有点不同,但不是太疯狂。 – callyalater

2

你永远设置node->nextNULL(用于head->nextcurrent->next路径)。使用malloc进行分配不会清除分配的内存,因此您需要自行完成此操作。

此外,当您添加的第二个元素,你迭代直到current达到NULL,但你永远不设置previous_node->next指向新的元素,所以你从来没有真正“链接”在你的链表什么。

另外,你shouldn't cast the result of malloc in C

2

最主要的原因,为什么你没有看到添加第二和后续节点的作用是,当你分配一个新的节点不是头节点,你的存储指向它只能在局部变量current的功能add()。您需要将其存储在前一节点的next指针中。与原来的代码比较:

struct node* current = head; 
    while (current->next != NULL) { 
     current = current->next; 
    } 
    current->next = malloc(sizeof(*current->next)); 

还要注意的是,作为@Lousy也观察到,你没有新节点的next指针设置为NULL。您必须这样做,直到您为这些字段分配一些值,其内容是不确定的。