在我的代码中找不到分段错误

时间:2018-05-31 01:56:01

标签: c segmentation-fault

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

typedef struct node{
    struct node* next;
    int value;
}Node;

int findLastNodeValue(Node* head){
     while(head -> next != NULL){
         head = head -> next;
     }
         return head -> value;
}


int main(){
    Node  *node1,node2;
    node1 = (Node   *)malloc(sizeof(Node);
    node2 = NULL;
    node1 -> next = node2;
    findLastNodeValue(node1);
    findLastNodeValue(node2);
    return 0;
}

此代码给出了分段错误。但我无法找到它为什么会发生。你能帮帮我解决这个问题。

2 个答案:

答案 0 :(得分:2)

您的代码存在多个问题:

  • 您正在malloc正在node1,但您没有在任何地方设置该值。每当您尝试访问value时,这都会产生未定义的行为-您可能会使程序崩溃或获得垃圾数据,这通常会更糟,因为这会导致代码的其他部分变得异常。

  • 您没有释放动态分配的内存。虽然对您而言这并不算什么大问题,但它告诉我您不熟悉动态分配的工作方式(此列表中的第一个要点也加强了我的信念)。每当您malloc时,总是free它(在C ++中,您有newdelete)并且(为防止意外行为)将指针设置为NULL

  • node2不是指针。 *中的Node *node1, node2;仅适用于第一个变量。每个连续变量还需要一个*,否则它将被分配在堆栈上。

  • 通过查看代码,您显然希望node2成为指针(否则,您将不会分配NULL作为其值:))。在这种情况下,您尝试访问next中的node2,但是node2初始化为NULL

    int findLastNodeValue(Node* head){ // You are passing node2, which is NULL
        while(head -> next != NULL){ // Can't access next of a NULL -> code breaks
            head = head -> next;
        }
    
        return head -> value;
    }
    

通常,请执行以下操作:

  • 尝试使用实例化节点的函数-由于这是C,因此您没有构造函数,我建议编写一个函数(或几个,具体取决于您需要多少功能)一个新节点。这样,您将确保至少没有机会不初始化节点

    例如:

    Node* createNode(int value) {
        Node* node = (Node *)malloc(sizeof(Node));
        if (!node) return NULL; // If malloc fails for some reason
        node -> value = value;
        node -> next = NULL;
    
        return node;
    }
    
  • 尝试使用删除节点的功能-如果有机会再次访问已删除的引用,请将其设置为NULL并相应地处理NULL

    例如:

    void deleteNode(Node** node) {
        if (!*node) return;
    
        free(*node);
        *node = NULL;
    }
    

    请注意,上面的代码不会删除next所引用的内容,因为我们只想删除传递给函数的节点。如果您有previous(在双链表的情况下),则必须首先访问next节点,将其previous的值设置为NULL,然后删除您当前的节点。

  • 无论何时传递指针,都要先始终检查该指针是否为NULL,然后再对它应该引用的数据进行任何处理。从一开始就将其与节点创建器功能结合在一起,可以确定没有传递未正确初始化的Node指针

现在,特别是关于您的功能,我将执行以下操作:

int findLastNodeValue(Node* head) {
     if (!head) return -1; // We have a null reference, so there is nothing else to do here; exit accordingly and check the return value to see if the function call has been successful

     while(head -> next != NULL) {
         head = head -> next;
     }

     return head -> value;
}

答案 1 :(得分:1)

findLastNodeValue(node2)是你最大的问题。当你向findLastNodeValue发送NULL时,你要做的第一件事是取消引用子句的NULL指针(head - &gt; next!= NULL)。

要解决此问题,您可以在while循环之前检查并处理findLastNodeValue函数中head为NULL时的情况。