我不久前开始用C编程,并试图创建一个词法分析器(我已经在Java中做过了(进行练习。作为一项练习,我为代币创建了一个链表。除了删除元素外,其他一切都很好。
token.h
#ifndef TOKEN_H
#define TOKEN_H
typedef struct TOKEN_STRUCT {
enum TokenType {
...
} type;
char* contents;
struct TOKEN_STRUCT* next;
size_t start_position, end_position;
} Token;
...
Token* init_token(enum TokenType type, char* contents, size_t start_position, size_t end_position);
Token* remove_token_last(Token* head);
...
#endif
token.c
#include "token.h"
...
Token* init_token(enum TokenType type, char* contents, size_t start_position, size_t end_position)
{
Token* token = (Token*) malloc(sizeof(struct TOKEN_STRUCT));
if(token == NULL) {
printf("Couldn't allocate memory for the token.n");
exit(EXIT_FAILURE);
}
token->type = type;
token->contents = contents;
token->start_position = start_position;
token->end_position = end_position;
return token;
}
// This is the function which throws the Segmentation fault
Token* remove_token_last(Token* head)
{
Token* current = head;
while(current->next != NULL)
current = current->next;
Token* return_token = current->next;
printf("remove: %u, %sn", return_token->type, return_token->contents); <- And this line creates the Segmentation fault.
current->next = NULL;
return return_token;
}
现在我的问题是:为什么它会抛出错误,难道我不能定义另一个指针变量(Token*current=…;(来存储下一个Token*(current->next(供以后使用吗?
此外,我是C语言编程的新手,我会学习一些答案,这些答案将帮助我摆脱这种情况。即使有什么我可以做得更好,也请纠正我!
编辑:我觉得有点傻,但我还是让这个问题继续存在吧。也许("希望如此"(有些人看起来和我一样漫不经心。:D问题是,"current->next"不能是NULL,因为当退出while循环时,由于这种情况,"current->next"将是NULL。
return_token
在尝试打印其字段时为null。
// This is the function which throws the Segmentation fault
Token* remove_token_last(Token* head)
{
Token* current = head;
while(current->next != NULL) // looping while current->next != NULL
current = current->next;
Token* return_token = current->next; // now its NULL so return_token is NULL too
// therefore in the printf you referencing to a NULL pointer fields which
// cause segmentation error
printf("remove: %u, %sn", return_token->type, return_token->contents); <- And this line creates the Segmentation fault.
current->next = NULL;
return return_token;
}