c-试图制作链表,出现seg错误



对C来说是个新手,但我正在尝试编写这个链表程序,但我一直收到Segmentation错误:11。我想我已经把它缩小到了链表创建中的问题——我把它标记为问题区域。当我评论掉这一部分时,seg错误不会发生。

我一直在复习纸上发生的事情,我不明白为什么它不起作用。也许我只是误解了指针或malloc的使用,因为我没有经验。

这个程序应该使用的示例文本文件:

>984932:39284 mus musculus okodvcxvmkw2e2p n
ATCTCAATCGCACTATCTAGCATGTCGTATGCTTGCATGTCGTAGTCGTn
ATGCTATGCTTACTCTATTTACGGCGCATCGTGATCGTAGGAGCGAGCTn
>984932:39284 mus huumoros okodvcxvmkw2e2p n
ATCTCAATCGCACTATCTAGCATGTCGTATGCTTGCATGTCGTAGTCGTn
ATGCTATGCTTACTCTATTTACGGCGCATCGTGATCGTAGGAGCGAGCTn
>984932:39284 mus pisces okodvcxvmkw2e2p n
ATCTCAATCGCACTATCTAGCATGTCGTATGCTTGCATGTCGTAGTCGTn
ATGCTATGCTTACTCTATTTACGGCGCATCGTGATCGTAGGAGCGAGCTn

我想做的事情:创建一个链接列表,其中每个节点都是上面的一个文本块。也就是说,每个节点都包含以">"开头的标头,以及作为所有ACTG的序列数据。在上面的示例文本文件中,除了列表中的头/尾节点之外,还有3个节点。

我是如何做到的(问题部分):已扫描字符。如果char是'>',那么我们知道我们在标头处,并且我们将以下所有字符读取到新节点的标头字段中,直到到达换行符为止。在这一点上,我们知道我们将按顺序读取数据。继续这样做,直到我们到达另一个'>',当我们到达时,重复。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int list_header_size = 200;
int list_data_size = 2000;
struct list{
    char *header;
    char *data;
    struct list *next;
    struct list *prev;
};
//append char onto a string
void append(char *s, char c){
    int len = strlen(s);
    s[len] = c;
    s[len + 1] = '';
}
int create_list(char *filename){
    FILE *fp = fopen(filename, "r");
    if(fp == NULL){
        printf("File could not be opened. Exiting..");
        exit(1);
    }
    //setup head - doesn't hold a char
    struct list *head = malloc(sizeof(struct list));
    head->next = NULL;
    head->header = NULL;
    head->data = NULL;
    head->prev = NULL;
    //setup tail - doesn't hold a char
    struct list *tail = malloc(sizeof(struct list));
    tail->next = NULL;
    tail->header = NULL;
    tail->data = NULL;
    tail->prev = NULL;
    /***scan the .fasta file, populate list***/
    //char holder
    char c;
    int list_size = 0;
    int i = 1;
    //pull single char from file until end of file is reached
    do{
        c = getc(fp);
        //******PROBLEM IS IN THIS SECTION********//
        //if header text is found
        if(c == '>'){
            //create a node
            struct list *temp = malloc(sizeof(struct list));
            //first case to setup head
            if(i == 1){
                head->next = temp;
                temp->prev = head;
                i = 0;
            }
            tail->next = temp;
            tail->prev = temp;
            //create space for header/sequence data in the new node
            temp->header = (char*) malloc(sizeof(list_header_size));
            temp->data = (char*) malloc(sizeof(list_sequence_size));
            //add current char to header
            append(temp->header, c);
            c = getc(fp);
            //put file's header data into node's header data
            while(c != 'n'){
                append(temp->header, c);
                c = getc(fp);
            }
            //put file's sequence data into node's sequence data
            while(c != '>' && c != EOF){
                append(temp->data, c);
            }
        }
        //*******END OF PROBLEM SECTION********//
    }while(c != EOF);
    /***end of scanning .fasta file and creating linked list***/
    return 1;
}
int main(int argc, char * argv[]){
    char *filename = (char*) malloc(80);
    //check options
    int i;
    for(i = 1; i < argc; i++){
        if(argv[i][0] == '-'){
            switch(argv[i][1]){     
                default:;
            }
        }else{
            //arg is filename
            filename = argv[i];
        }
    }
    create_list(filename);
    return 1;
}

最直接的事情是:

  //create space for header/sequence data in the new node
  temp->header = (char*) malloc(sizeof(list_header_size));
  temp->data = (char*) malloc(sizeof(list_sequence_size));

我认为应该是这样的:

  //create space for header/sequence data in the new node
  temp->header = malloc(list_header_size);
  temp->data = malloc(list_sequence_size);

如果你是C的新手,这里可能还有其他东西,但mallocs和它们的大小总是我首先检查的,而这个是不对的。

编辑另一个问题:

现在已经分配了缓冲区,但是append()函数期望它们从一开始就被零终止。事实并非如此。添加此:

  temp->header = malloc(list_header_size);
  temp->data = malloc(list_sequence_size);
  temp->header[0] = temp->data[0] = 0; // <=== this

老实说,由于这些大小是固定的,我宁愿你只声明这样的实际节点结构:

struct list{
    char header[200];
    char data[2000];
    struct list *next;
    struct list *prev;
};

并且完全避免所有额外的分配,只分配节点而不分配它们的字段。如果字段大小变得动态,则需要更改,但在此之前,请保持简单。

我将查看您的append(...)函数,以及您向其中输入的数据。您对该功能的第一次调用是

append(temp->header, c);

并且不能保证CCD_ 2为零。它可以指向任何东西,尽管大多数编译器会将其归零(或试图这样做)。使用calloc而不是malloc

相关内容

  • 没有找到相关文章

最新更新