当我调用这个函数时,我的代码总是在
strcmp
中中断并返回一个 Segmentation Error
没有提供更多信息。
stop_t *getStop(char *name) {
node_t *current = stop_list_head;
stop_t *stop;
while (current != NULL) {
stop = current->stop;
if (stop != NULL) {
if (stop->name != NULL) {
if (strcmp(stop->name, name) == 0) {
return stop;
}
}
}
current = current->next;
}
return NULL;
}
当我插入一个
printf("%s", stop->name);
它返回相同的分段错误但是在printf
.
我该如何解决这个问题?
最小可复制示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH_STOP 50
typedef struct {
int routeCounter;
double latitude;
double longitude;
char name[MAX_LENGTH_STOP + 1];
} stop_t;
typedef struct node {
stop_t *stop;
struct node *next;
} node_t;
void printStopList();
node_t *stop_list_head = NULL;
int main() {
stop_t *stopPtr = NULL;
stop_t stop;
char name[MAX_LENGTH_STOP + 1];
/* Input Example: Praca de Espanha ; */
fgets(name, BUFSIZ, stdin);
stopPtr = getStop(name);
/* Create new stop if it doesn't exist already, else print error.*/
if (stopPtr == NULL) {
generateStop(name);
} else {
printf("<Error 01>: Stop already exists.\n");
}
}
/* Determines if the stop already exists based on the name */
stop_t *getStop(char *name) {
node_t *current = stop_list_head;
stop_t *stop;
while (current != NULL) {
stop = current->stop;
if (stop != NULL) {
if (stop->name != NULL) {
if (strcmp(stop->name, name) == 0) {
return stop;
}
}
}
current = current->next;
}
return NULL;
}
/* Generates a stop instance and adds it to the global linked list*/
void generateStop(char name[]) {
stop_t *stop = NULL;
stop = (stop_t *)malloc(sizeof(stop_t));
strcpy(stop->name, name);
stop->routeCounter = 0;
addStopToList(stop);
free(stop);
}
/* Adds created stops to a global linked list (stop_list_head)*/
void addStopToList(stop_t *stop) {
node_t *new_node = (node_t *)malloc(sizeof(node_t));
node_t *current;
new_node->stop = stop;
new_node->next = NULL;
if (stop_list_head == NULL) {
stop_list_head = new_node;
} else {
current = stop_list_head;
while (current->next != NULL) {
current = current->next;
}
current->next = new_node;
}
free(new_node);
}
存在多个问题:
你在应该分配它们的函数中释放了新分配的结构。这会在稍后读取时导致未定义的行为,例如:当
strcmp
访问stop->name
时
你阅读
name
fgets
传递了一个无效的大小 BUFSIZ
比 MAX_LENGTH_STOP + 1
大得多。这可能会导致缓冲区溢出
你不测试
fgets()
的返回值,如果从空文件重定向会导致无效行为。
fgets()
在 name
数组的末尾留下尾随换行符:它将被存储到停止列表中。
strcpy(stop->name, name);
如果name
参数比name
结构中的stop_t
字段长,则可能导致缓冲区溢出。
最小的例子实际上并没有导致你报告它的分段错误,因为停止列表是空的。
这里是修改版:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LENGTH_STOP 50
typedef struct stop {
int routeCounter;
double latitude;
double longitude;
char name[MAX_LENGTH_STOP + 1];
} stop_t;
typedef struct node {
stop_t *stop;
struct node *next;
} node_t;
node_t *stop_list_head;
/* Determines if the stop already exists based on the name */
stop_t *getStop(const char *name) {
node_t *current = stop_list_head;
while (current != NULL) {
stop_t *stop = current->stop;
if (stop != NULL && strcmp(stop->name, name) == 0) {
return stop;
}
current = current->next;
}
return NULL;
}
/* Adds created stops to a global linked list (stop_list_head)*/
void addStopToList(stop_t *stop) {
node_t *new_node = (node_t *)malloc(sizeof(node_t));
if (new_node == NULL) {
perror("cannot allocate node_t");
exit(1);
}
new_node->stop = stop;
new_node->next = NULL;
if (stop_list_head == NULL) {
stop_list_head = new_node;
} else {
node_t *current = stop_list_head;
while (current->next != NULL) {
current = current->next;
}
current->next = new_node;
}
}
/* Generates a stop instance and adds it to the global linked list*/
void generateStop(const char *name) {
stop_t *stop = (stop_t *)calloc(sizeof(stop_t), 1);
if (stop == NULL) {
perror("cannot allocate stop_t");
exit(1);
}
strncat(stop->name, name, sizeof(stop->name) - 1);
addStopToList(stop);
}
int main(void) {
for (;;) {
char name[MAX_LENGTH_STOP + 2];
/* Input Example: Praça de Espanha ; */
if (!fgets(name, sizeof name, stdin))
return 1;
/* strip the trailing newline if present */
name[strcspn(name, "\n")] = '\0';
/* stop on an empty line */
if (*name == '\0')
break;
/* Create new stop if it doesn't exist already, else print error.*/
if (getStop(name)) {
printf("<Error 01>: Stop already exists: %s\n", name);
} else {
generateStop(name);
}
}
return 0;
}