完整代码:https://gist.github.com/IamSlightly/5debd2373231a62c0a44665902e9ca7f
不确定为什么会发生这种情况,但它发生在第43行,当printf试图访问返回值时。
struct node* kv = Lookup (13);
if (kv)
printf ("%sn", kv->val_ptr);
struct node* Lookup(int x){
struct node *holder;
holder = head;
while ((holder->key!=x) && (holder->next!=NULL)){
holder = holder->next;
}
if (holder->key==x) {
printf("nlets try this shit againn");
return holder;
} else {
printf("n*** %d is not in the linked_list ***n", x);
return NULL;
}
}
如果系统崩溃:
printf ("%sn", kv->val_ptr);
则可以肯定kv
或kv->val_ptr
不是指向"kosher"的东西。
因为你的Lookup
代码似乎排除了返回一个无效的指针(当然假设你没有搞砸的创建的链表),很可能val_ptr
字段没有被正确设置,或者它指向的东西不是一个字符串。
最好的方法是使用调试器(如果没有合适的调试器,可以使用printf
行),并在尝试使用之前检查值。这将极大地帮助你找出根本原因。
如果你要去printf
路线(我更喜欢一个调试器,但它并不总是一个选项),我会看下面的代码,放在你自己的if (kv)
行之前:
if (kv) {
printf ("Starting DEBUGn");
fflush (stdout); fsync (fileno (stdout));
printf ("kv as pointer is %pn", kv);
fflush (stdout); fsync (fileno (stdout));
printf ("kv->val_ptr as pointer is %pn", kv->val_ptr);
fflush (stdout); fsync (fileno (stdout));
printf ("kv->val_ptr as char[10] is %10.10sn");
fflush (stdout); fsync (fileno (stdout));
printf ("Ending DEBUGn");
fflush (stdout); fsync (fileno (stdout));
}
这展示了如何编写调试语句,使它们在核心转储停止输出之前被刷新。
基本上,你需要做的是逐渐缩小问题范围,直到你可以将其隔离到特定的行,然后找出该行的问题:-)
作为题外话,如果一个空列表将包含
head
被设置为NULL
,那么Lookup
代码将在您身上崩溃。这可能不是这里的情况,因为你已经说它是实际的printf
行崩溃。
更好的格式是:
struct node* Lookup (int x) {
struct node *holder = head;
while (holder != NULL)
if (holder->key == x)
return holder;
return NULL;
}
此外,根据您提供的链接中的代码,您可能希望在头文件中添加函数原型。你有结构和变量,如head
,但这是一个好主意,任何代码使用你的实现有正确定义的定义,其中的函数。例如,它应该包含如下内容:
int Insert(int, char*, int);
用于Insert
函数,对于您希望调用的其他函数也是如此。