链表插入崩溃程序中的strcmp
strcmp in Linked List insertion crashing program
作为作业的一部分,我应该用 c 语言实现一个单向链表。
我以前用几种不同的语言做过很多次,但经过几个小时的痛苦后,我陷入了使用 strcmp 的问题。
这是我正在使用的结构:
typedef struct node {
char *name;
float score;
struct node *next;
} node;
问题特定于插入函数,它应该类似于插入排序,因为我需要将列表中的节点按字母顺序排序。(我的教授指定插入函数执行排序,尽管不称其为插入排序)。
void insert(node **start, char *name, float score) { // to insert a record into the linked list sorted by name in dictionary order.
//create new node
node *n_node = new_node(name, score);
node *current;
current = *start;
if (current != NULL) { //-----------if list is not empty
node *prev = NULL;
if (current->next != NULL) { //--if list has more than 1 element
while (current != NULL && strcmp(name, current->name) > 0) { //cycle through list to sorted insertion point
// ^^^^^^^Problem Here^^^^^^^^
//while name is greater than current name, means lower on alphabet (z>a)
prev = current;
current = current->next;
}
if (current != NULL) { //-----not at end of list
//once current is not < new node, connect between prev and current
prev->next = n_node;
n_node->next = current;
} else { // ------------------at end of list
prev->next = n_node;
}
} else { //-----------------------list has only one element
current->next = n_node;
}
} else { //--------------------------List is empty - assign new node as first element
*start = n_node;
}
}
问题是我的程序在没有任何错误或警告的情况下崩溃和烧毁(我正在使用带 CDT 的 eclipse)。
该程序在以下情况下运行良好
while (current != NULL && strcmp(name, current->name) > 0)
修改为
while (current != NULL /*&& strcmp(name, current->name) > 0*/)
.
我觉得 name
或 current->name
导致 strcmp
的操作出现问题,但我似乎无法解决这个问题。
编辑:
我要补充一点,这个函数是从另一个函数调用的,它从包含成对名称和标记的文件中检索和标记字符串,但我的测试没有表明它通过调用传递了错误的字符串或字符。
有关更多详细信息,这是我的 new_node 函数:
node *new_node(char *name, float score) {
node *new = (struct node*) malloc(sizeof(struct node));
new->name = malloc(strlen(name) + 1);
strcpy(new->name, name);
new->score = score;
new->next = NULL;
return new;
}
(我意识到使用 new
作为节点名称并不明智,我会更改它)
和调用插入的函数:
int data_import(node **startp, char *infilename) { // to import data from the file and insert .
int max_line = 100;
char line[max_line];
char delimiters[] = ",";
char name[500] = "";
char *namep;
namep = &name[0];
float score = 0.0f;
int i = 0;
FILE *fi;
char *token;
// open file to read
fi = fopen(infilename, "r");
if (fi == NULL) { // Cannot open the file.
perror("error");
return 0;
}
// read each line, increase counter, retrieve data
while (fgets(line, max_line, fi) != NULL) {
//fputs(line, stdout); //console output confirmation
token = strtok(line, delimiters);
strcpy(namep, token);
token = strtok(NULL, delimiters); //increment token to mark variable
score = atof(token);
insert(startp, namep, score);
i++;
}
//close file
fclose(fi);
return i;
}
如果您将名为 apple 的元素作为第一个元素并尝试添加名为 about 的元素,会发生什么情况?
你会被直接扔出下面的 while 循环,你的 prev 将被取消分配:
while (current != NULL && strcmp(name, current->name) > 0) { //cycle through list to sorted insertion point
// ^^^^^^^Problem Here^^^^^^^^
//while name is greater than current name, means lower on alphabet (z>a)
prev = current;
current = current->next;
}
我觉得这个特定部分很可疑:
之后您将进入以下例程:
if (current != NULL) { //-----not at end of list
//once current is not < new node, connect between prev and current
prev->next = n_node;
n_node->next = current;
}
因为您的 *prev 未分配并且您尝试访问它 (prev->next = n_node;)。您将在此处崩溃。
作为作业的一部分,我应该用 c 语言实现一个单向链表。 我以前用几种不同的语言做过很多次,但经过几个小时的痛苦后,我陷入了使用 strcmp 的问题。 这是我正在使用的结构:
typedef struct node {
char *name;
float score;
struct node *next;
} node;
问题特定于插入函数,它应该类似于插入排序,因为我需要将列表中的节点按字母顺序排序。(我的教授指定插入函数执行排序,尽管不称其为插入排序)。
void insert(node **start, char *name, float score) { // to insert a record into the linked list sorted by name in dictionary order.
//create new node
node *n_node = new_node(name, score);
node *current;
current = *start;
if (current != NULL) { //-----------if list is not empty
node *prev = NULL;
if (current->next != NULL) { //--if list has more than 1 element
while (current != NULL && strcmp(name, current->name) > 0) { //cycle through list to sorted insertion point
// ^^^^^^^Problem Here^^^^^^^^
//while name is greater than current name, means lower on alphabet (z>a)
prev = current;
current = current->next;
}
if (current != NULL) { //-----not at end of list
//once current is not < new node, connect between prev and current
prev->next = n_node;
n_node->next = current;
} else { // ------------------at end of list
prev->next = n_node;
}
} else { //-----------------------list has only one element
current->next = n_node;
}
} else { //--------------------------List is empty - assign new node as first element
*start = n_node;
}
}
问题是我的程序在没有任何错误或警告的情况下崩溃和烧毁(我正在使用带 CDT 的 eclipse)。
该程序在以下情况下运行良好
while (current != NULL && strcmp(name, current->name) > 0)
修改为
while (current != NULL /*&& strcmp(name, current->name) > 0*/)
.
我觉得 name
或 current->name
导致 strcmp
的操作出现问题,但我似乎无法解决这个问题。
编辑: 我要补充一点,这个函数是从另一个函数调用的,它从包含成对名称和标记的文件中检索和标记字符串,但我的测试没有表明它通过调用传递了错误的字符串或字符。
有关更多详细信息,这是我的 new_node 函数:
node *new_node(char *name, float score) {
node *new = (struct node*) malloc(sizeof(struct node));
new->name = malloc(strlen(name) + 1);
strcpy(new->name, name);
new->score = score;
new->next = NULL;
return new;
}
(我意识到使用 new
作为节点名称并不明智,我会更改它)
和调用插入的函数:
int data_import(node **startp, char *infilename) { // to import data from the file and insert .
int max_line = 100;
char line[max_line];
char delimiters[] = ",";
char name[500] = "";
char *namep;
namep = &name[0];
float score = 0.0f;
int i = 0;
FILE *fi;
char *token;
// open file to read
fi = fopen(infilename, "r");
if (fi == NULL) { // Cannot open the file.
perror("error");
return 0;
}
// read each line, increase counter, retrieve data
while (fgets(line, max_line, fi) != NULL) {
//fputs(line, stdout); //console output confirmation
token = strtok(line, delimiters);
strcpy(namep, token);
token = strtok(NULL, delimiters); //increment token to mark variable
score = atof(token);
insert(startp, namep, score);
i++;
}
//close file
fclose(fi);
return i;
}
如果您将名为 apple 的元素作为第一个元素并尝试添加名为 about 的元素,会发生什么情况?
你会被直接扔出下面的 while 循环,你的 prev 将被取消分配:
while (current != NULL && strcmp(name, current->name) > 0) { //cycle through list to sorted insertion point
// ^^^^^^^Problem Here^^^^^^^^
//while name is greater than current name, means lower on alphabet (z>a)
prev = current;
current = current->next;
}
我觉得这个特定部分很可疑:
之后您将进入以下例程:
if (current != NULL) { //-----not at end of list
//once current is not < new node, connect between prev and current
prev->next = n_node;
n_node->next = current;
}
因为您的 *prev 未分配并且您尝试访问它 (prev->next = n_node;)。您将在此处崩溃。