【问题标题】:I keep getting a segfault when trying to pass a struct node* and then print using printf尝试传递 struct node* 然后使用 printf 打印时,我不断收到段错误
【发布时间】:2016-09-08 04:43:55
【问题描述】:

完整代码在这里:https://gist.github.com/IamSlightly/5debd2373231a62c0a44665902e9ca7f

不确定为什么会发生这种情况,但是当 printf 尝试访问返回值时,它发生在第 43 行。

struct node* kv = Lookup (13);
if (kv)
    printf ("%s\n", 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 again\n");
    return holder;
  } else {
    printf("\n*** %d is not in the linked_list ***\n", x);
    return NULL;
  }
}

【问题讨论】:

  • kv->val_ptr 的值是多少?
  • 使用调试器单步调试代码,查看失败时变量的值。
  • 尝试在你的头文件中包含一些函数原型。现在main.c 正在拉入linked_list.h,其中包含结构定义,但不 包含Insert、Lookup 等的原型。因此,所有这些函数都需要关于返回 int 并带有可变参数列表的函数的隐式声明。我愿意打赌您的构建/运行装备int 和struct node * 的大小不相同。因此int Lookup() 正在返回一些东西,但它肯定不是一个有效的指针。顺便说一句,您应该会收到大量关于此的警告。
  • 我不敢相信我没有这样做
  • @plzhelpme 可能会更糟。您可以在完全掩盖该问题的 32 位平台上运行/测试它,认为生活很美好,然后在 64 位平台上进行一些专业测试并见证您的成绩坦克。

标签: c linked-list segmentation-fault nodes


【解决方案1】:

如果你崩溃了:

printf ("%s\n", kv->val_ptr);

那么可以肯定的是,kv 或 kv->val_ptr 没有指向“kosher”的东西。

由于您的Lookup 代码似乎排除了返回无效指针(当然假设您没有搞砸链接列表的创建),很可能val_ptr 字段没有' 设置不正确,或者它指向的不是字符串。

最好的办法是使用调试器(如果没有合适的调试器,则使用printf 行)并在尝试使用它们之前检查值。这将极大地帮助您找出根本原因。

如果你要走printf 路线(我更喜欢调试器,但它并不总是一个选项),我会查看如下代码,放在你自己的if (kv) 行之前:

if (kv) {
    printf ("Starting DEBUG\n");
    fflush (stdout); fsync (fileno (stdout));

    printf ("kv as pointer is %p\n", kv);
    fflush (stdout); fsync (fileno (stdout));

    printf ("kv->val_ptr as pointer is %p\n", kv->val_ptr);
    fflush (stdout); fsync (fileno (stdout));

    printf ("kv->val_ptr as char[10] is %10.10s\n");
    fflush (stdout); fsync (fileno (stdout));

    printf ("Ending DEBUG\n");
    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 函数,您希望调用的其他函数同上。

【讨论】:

  • 非常感谢你,我会试一试的。
  • 启动 DEBUG holder 作为指针是 0x7f9e3a80c000 holder->val_ptr 作为指针是 0x7f9e3a80c200 分段错误:11 只是要弄清楚如何处理这个
  • @plzhelpme,那么您的问题是您将val_ptr 视为字符串,而事实并非如此。这可能就像确保它是 nul 终止一样简单,也可能像其他地方引起的内存损坏一样复杂。但是,调试方法最终将引导您找到答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-27
  • 2016-05-05
相关资源
最近更新 更多