我确定我已经搞砸了我的指针,或者可能是最初的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;
}