【问题标题】:segfault with linked list带链表的段错误
【发布时间】:2012-11-06 06:11:05
【问题描述】:

我在使用 C 中的链表时遇到了问题,我只在 C++ 中完成过类似这样的数据结构。

Gdb 给了我一个

Program received signal SIGSEGV, Segmentation fault. 0x0804a23c in addArg (base=0x1, argument=0x804e410 "is") at myshell.c:42 42 while ( (curr != NULL) && (curr->n != NULL) )

我熟悉与内存有关的分段错误,但我认为我已正确分配内存。我做错了什么?

addArg 被称为addArg(currentCmd->args, lexeme);,currentCmd 是一个指向节点结构的指针

struct lnode {
 char *x;
 struct lnode *n;
};


struct node
  {
    char *command;
    struct lnode *args;
    int input;
    int output;
    int error;
    char *in;
    char *out;
    char *err;
    struct node *next;
    struct node *prev;
  };



void addArg(struct lnode *base, char *argument)
 {
 struct lnode *curr = base;

//this is line 42
  while ( (curr != NULL) && (curr->n != NULL) )
    curr = curr->n;

   curr -> n = malloc(sizeof(struct lnode));
   curr = curr->n;
   curr->x = strdup(argument);
   curr->n = NULL;
 }




struct node* createNode(char *command_, int input_, int output_, int error_, char *in_, char *out_, char *err_, struct node *prev_)
  {
  struct node *n;
  n = malloc(sizeof (struct node));
  n->command = strdup(command_);
  n->prev = prev_;
  n->next = NULL;
  n->input = input_;
  n->output = output_;
  n->error = error_;
  n->in = in_;
  n->out = out_;
  n->err = err_;
  n->args=malloc(sizeof(struct lnode));

 return n;
  }

【问题讨论】:

  • 我将答案改为评论,因为这不太可能是 this 问题的原因。在while-loop 之后,curr 可能是NULL,但您尝试设置它的成员,这将导致稍后出现问题。确保你解决了这个问题,否则你很快就会再次回到这里;-)(澄清:发送一个 NULL 指针作为该函数的参数,你最终会得到一个很好的 SIGSEGV 信号:)
  • 据我了解,curr 指向传递给函数的参数,该参数指向节点结构中的“lnode args”成员。
  • 如果addArg 函数的base 参数是NULL,那么您将出现段错误。在这种情况下,问题很可能正如 John Kugelman 所说。

标签: c linked-list segmentation-fault


【解决方案1】:

看起来currentCmd->args 是一个无效指针。也许是指向free()d 内存的指针。或未初始化的指针,或指向超出范围的局部变量的指针(尽管后两者在这里似乎不是这种情况)。

或者您可能在程序的其他地方不小心覆盖了越界内存。指针问题并不总是出现故障。有时它们在较早的代码中,甚至是不相关的代码。

【讨论】:

  • 我编辑了代码来初始化节点结构中的args,分配内存后为NULL,但它没有解决问题。
【解决方案2】:

我通过将lnode *args 变为lnode args 并对内存管理进行必要的更改来解决此问题。

【讨论】:

    【解决方案3】:

    我可以从您的 gdb 输出中看到,while ( (curr != NULL) && (curr->n != NULL) ) 的问题是,如果 curr == NULL 您仍在尝试访问 curr->n 进行比较,因此您应该将该条件更改为仅比较 curr,并且仅在 curr 不为 null 时处理 curr->n,如果 curr->n == NULL 可能会立即破坏 cicle。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多