【问题标题】:Linked list segfault on insertion/printing插入/打印时的链表段错误
【发布时间】:2015-05-08 23:56:19
【问题描述】:

我有一个带有结构和插入/打印函数的链表,如下所示,

typedef struct node{
    int size;
    int day;
    int year;
    char* month;
    char* fileName;
    struct node *next;
}node;

void insert(node ** head, int size, int year, int day, char* month, char* fileName){
    node * newNode = (node*)malloc(sizeof(node));
    newNode->size = size;
    newNode->fileName = fileName;
    newNode->day = day;
    newNode->month = month;
    newNode->year = year;
    newNode->next = *head;
    *head = newNode;
    puts("insert called");
    //printf("head is %s\n", newNode->fileName);
}
void print_list(node * head) {
    node * current = head;
    while (current != NULL){
        puts("got here");
        printf("head %s\n", current->fileName);
        current = current->next;
        printf("next filename %s\n", current->fileName);
    }
}

当我调用插入函数时,它会按照我调用该函数的次数打印“插入调用”消息。所以我的猜测是插入函数不是问题。

我的问题是在 print 函数打印列表中的前几个节点后我得到一个 Segfault(前两个节点工作正常!)

这是调用插入函数的其余代码, 我不认为这是她的问题,但我可能弄错了:

所有对链表函数的调用都在底部

void p5aFlag(char* pathName){
    DIR* d;
    struct dirent *dir;
    struct stat s;
    struct tm *tp;
    char* fileName;
    char temp2[strlen(pathName)];
    char * month;
    time_t t;
    d = opendir(pathName);
    int year;
    int day;
    int size;
    node *head = NULL;
    int flag = 0;

    if(d){   //While there are more files in the directory, keep reading them off
        while ((dir = readdir(d)) != NULL){
            fileName = dir->d_name; //store the name of the directory that was just read in fileName
            strcpy(temp2,pathName); // copy the directory name into temp2

            if(strcmp(fileName, ".") != 0 && strcmp(fileName, "..") != 0){ // get file info if the file isn't "." or ".."
                strncat(temp2,"/",2); // prepare the path to lead to another file
                strncat(temp2, fileName, 15); // append the fileName to the path, now we can open this file
                if(stat(temp2, &s) == -1 ){ // if we cannot get information for this file, print error message and exit
                    fprintf(stderr, "couldnt get file info for %s\n", fileName);
                }
                t = s.st_mtime; //store the time that the file was last modified in t
                tp = localtime(&t); // convert to local time
                switch(tp->tm_mon){  // switch to change months from [0-11] to [Jan-Dec]
                    case 0:
                    month = "Jan";
                    break;
                    case 1:
                    month = "Feb";
                    break;
                    case 2:
                    month = "Mar";
                    break;
                    case 3:
                    month = "Apr";
                    break;
                    case 4:
                    month = "May";
                    break;
                    case 5:
                    month = "Jun";
                    break;
                    case 6:
                    month = "Jul";
                    break;
                    case 7:
                    month = "Aug";
                    break;
                    case 8:
                    month = "Sep";
                    break;
                    case 9:
                    month = "Oct";
                    break;
                    case 10:
                    month = "Nov";
                    break;
                    case 11:
                    month = "Dec";
                    break;
                    default:
                    break;
                }
                flag = 1;
            }
            if(flag == 1){
                year = 1900 + tp->tm_year;
                size = s.st_size;
                day = tp->tm_mday;
                insert(&head, size, year, day, month, fileName);
                flag = 0;
            }

            temp2[0]= '\0';
            flag = 0;
        }
        //search(head, ".emacs");
        print_list(head);
        closedir(d); // close the directory
    }
}

我不确定为什么会这样。任何帮助将不胜感激。

【问题讨论】:

    标签: c struct linked-list


    【解决方案1】:

    打印最后一个元素时会出现段错误,因为您将 current 设置为 current->next 但在打印下一个文件名之前不要检查它是否为 NULL

    void print_list(node * head) {
        node * current = head;
        while (current != NULL){
            puts("got here");
            printf("head %s\n", current->fileName);
            current = current->next;
            if(current != NULL)   /// add this check
                printf("next filename %s\n", current->fileName);
        }
    }
    

    这里还有一个毫无意义的分配和内存泄漏:

    node *head = (struct node *) malloc( sizeof(node));
    head = NULL;
    

    您分配了一个节点,但随后通过将 head 设置为 NULL 来丢失对它的任何引用。您可以像这样初始化为NULL

    node *head = NULL;
    

    【讨论】:

    • 一般(不要强制转换 malloc)注意:node *head = malloc (sizeof *head); 就足够了。 (尽管将其设置为NULL 的问题)@samgak,这不是针对您,只是针对那些阅读的人。很好的答案。
    • 感谢您的输入,但是我已经进行了更改,现在我在打印头部后出现总线错误。
    • 这不会仅由检查 NULL 指针引起,它是您代码中的一个单独问题。您应该做的一件事是复制文件名字符串以存储在您的节点中,而不是使用从 readdir 返回的指针,该指针指向每次调用 readdir 时都会被覆盖的字符串。
    • @SamWylock - SIGBUS 通常意味着您正在尝试访问非法地址。最后一个node 的成员next 是否初始化为NULL?如果没有,那么这将是你的罪魁祸首。
    猜你喜欢
    • 2015-05-18
    • 2015-12-28
    • 1970-01-01
    • 2013-01-01
    • 2017-11-12
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    相关资源
    最近更新 更多