strcmp() C 中的段错误

问题描述 投票:0回答:1

当我调用这个函数时,我的代码总是在

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);
}
c pointers segmentation-fault strcmp
1个回答
0
投票

存在多个问题:

  • 你在应该分配它们的函数中释放了新分配的结构。这会在稍后读取时导致未定义的行为,例如:当

    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;
}
© www.soinside.com 2019 - 2024. All rights reserved.