访问链表时出现分段错误 11

Segmentation fault 11 when accessing linked list

本文关键字:分段 错误 链表 访问      更新时间:2023-10-16

我确定我已经搞砸了我的指针,或者可能是最初的NULL,但我无法弄清楚。

我正在尝试将链表写入文本文件:

write_out(node *ll){
    ofstream out;
    out.open("output.txt");
    if (!out.is_open()) exit(EXIT_FAILURE);
    cout << ll->value;
    //stuff to write out
}

和:

struct node {
    int value;
    node *next;
}

但是这条线cout << ll->value导致Segmentation fault: 11,但我不明白为什么。

我已经注释掉了我实际要写的代码,因为这无关紧要,问题显然在于我(缺乏)对上述工作原理的理解。

我调用write_out(linkedlist) node* linkedlist指向第一个节点的位置。

这发生在以下之后:

read_in(node *ll){
    ifstream data; //opened and checked open as above for out
    int v;
    ll = new node;
    node *tmp = ll;
    data >> tmp->value;
    while(data >> v){
        tmp->next = new node;
        tmp = tmp->next;
        tmp->value = v;
    }
    tmp->next = NULL;  //thanks @sharth
}

哪个肯定没有离开ll = NULL

read_in(node *ll){

ll按值传递的参数。这意味着在read_in内部对它的任何更改都只是局部的,在它外部没有影响。因此,read_in完成后,指向列表头部的指针仍然NULL(假设这是您初始化指针时使用的指针)。因此,使用 NULL 参数调用 write_out 会取消引用 NULL 指针,这将导致 SIGSEGV。

我可以猜到问题出在将新节点添加到列表中的函数中。

我想你做类似的事情

void add_node( node *n, int value );
node *linkedlist = NULL;
add_node( linkedlist, somevalue );

在这种情况下,函数内部 linkedlist 的任何更改都不会影响原始对象 linkedlist。所以它仍然等于 NULL。因此,当您尝试输出列表并使用

cout << ll->value;

ll 等于空。

只是一个简单的例子来添加@Michael Foukarakis指出的内容

#include<iostream>
void this_dont_change_ptr(int* a, int val){
    a = new int;
    *a = val;   
}
void this_changes_ptr_itself(int** a, int val){
    *a = new int;
    *(*a) = val; 
}
int main(){
    int *my_ptr = NULL;
    this_dont_change_ptr(my_ptr, 5);
    if(my_ptr == NULL){
        std::cout << "In fact, ptr is still NULL" << std::endl;
    }
    // What I do with allocated memo??
    // grants that my_ptr is NULL again
    my_ptr = NULL;  
    this_changes_ptr_itself(&my_ptr, 5);
    if(my_ptr == NULL){
        std::cout << "MUST never get here!" << std::endl;
    }
    else{
        std::cout << "Now we have a new value " << *my_ptr << std::endl;    
    }
    delete my_ptr;  
    return 0;
}