我在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;
}
看起来currentCmd->args
是一个无效的指针。也许是指向free()
d内存的指针。或者一个未初始化的指针,或者一个指向超出范围的局部变量的指针(尽管后两个在这里似乎不是这种情况)。
或者,您可能不小心覆盖了程序中其他位置的越界内存。指针问题并不总是在故障点;有时它们在较早的代码中,甚至是不相关的代码。
我通过将lnode *args
变成lnode args
并对内存管理进行所需的更改来解决此问题。
我从您的 gdb 输出中看到,while ( (curr != NULL) && (curr->n != NULL) )
的问题在于,如果 curr == NULL,您仍在尝试访问 curr->n 进行比较,因此您应该将该条件更改为仅比较 curr,并且仅在 curr 不为 null 时才处理 curr->n,如果 curr->n == NULL,可能会立即破坏 cicle。