1

我只是想在一个变量中转换一个String(从文件中的一行读取) 。long long我的问题是我得到分段错误,我不知道为什么......这是代码:(我在“3° Call”函数上对错误发表了评论)

#define CAPACITY (unsigned long long) 11
#define INTEGERS_PATH // the path to the file I wish to read

typedef struct {
    void** array;
    unsigned long long el_num;
    unsigned long long array_capacity;
    int (*compare)(void*,void*);
} GenericArray;

// used for compare elements
struct record{
    char* string_field; // used in case the GenericArray is made of strings items
    long long integer_field; // used in case the GenericArray is made of long long items
};

// END OF STRUCTS ---------------------------------------------------------------------------------
// BEGIN OF FUNCTIONS -----------------------------------------------------------------------------

int main(int argc, char const *argv[]) {
    test_with_comparison_function(compare_record_int_field);
    return (EXIT_SUCCESS);
}

// Compare function passed to generic_array_create() for create the GenericArray
static int compare_record_int_field(void* r1_p,void* r2_p){
    if(r1_p == NULL){
        fprintf(stderr,"compare_record_int_field: the first parameter is a null pointer");
        exit(EXIT_FAILURE);
    }
    if(r2_p == NULL){
        fprintf(stderr,"compare_record_int_field: the second parameter is a null pointer");
        exit(EXIT_FAILURE);
    }

    struct record *rec1_p = (struct record*)r1_p;
    struct record *rec2_p = (struct record*)r2_p;

    if(rec1_p->integer_field < rec2_p->integer_field){
        return(1);
    }
    return(0);
}

// 1° Call
static void test_with_comparison_function(int (*compare)(void*, void*)) {
    GenericArray* array = generic_array_create(compare);
    load_array(array);
    print_array(array); // it prints the array
    free_array(array); // it frees the memory alocated by the array
}

// 2° Call
GenericArray *generic_array_create(int (*compare)(void*,void*)){
    GenericArray *array = malloc(sizeof(GenericArray));
    if(array == NULL){
        fprintf(stderr, "generic_array_create: unable to allocate memory for the generic array");
        exit(EXIT_FAILURE);
    }

    array->array = malloc(CAPACITY * sizeof(void*));
    array->el_num = 0;
    array->array_capacity = CAPACITY;
    array->compare = compare;

    return(array);
}

// 3° Call
static void load_array(GenericArray* array){
    clock_t start = clock(); // for timing

    printf("\nLoading data from file...\n");

    FILE * dataset_p = fopen(INTEGERS_PATH, "r");
    if(dataset_p == NULL){
        fprintf(stderr,"main: unable to open the file");
        exit(EXIT_FAILURE);
    }

    char *read_line_p;
    char buffer[1024];
    int buf_size = 1024;

    while(fgets(buffer, buf_size, dataset_p) != NULL){
        read_line_p = malloc((strlen(buffer) + 1) * sizeof(char));
        strcpy(read_line_p, buffer);
        char *string_field_in_read_line_p = strtok(read_line_p, "\n");
        char *integer_field_in_read_line_p = strtok(NULL, "\n");

        char *string_field_1 = malloc((strlen(string_field_in_read_line_p) + 1) * sizeof(char));
        char *string_field_2 = malloc((strlen(string_field_in_read_line_p) + 1) * sizeof(char));

        strcpy(string_field_1,string_field_in_read_line_p);
        strcpy(string_field_2,string_field_in_read_line_p);

        /* Here begins errors (SEGMENTATION FAULT) */
        int integer_field = atoi(integer_field_in_read_line_p); 
        long long integer_field = strtoll(integer_field_in_read_line_p, (char **) NULL, 10);

        struct record *record_p = malloc(sizeof(struct record));
        record_p->string_field = string_field_1;
        record_p->integer_field = integer_field;

        generic_array_add(array, (void*) record_p);

        free(read_line_p); 
    }

    fclose(dataset_p);
    printf("\nData loaded\n");
}

这是我要阅读的文件,它是一个简单的.txt文件:

9
8
7
6
5
4
3
2
2
1
10
4

1 回答 1

3

问题是这三行:

while(fgets(buffer, buf_size, dataset_p) != NULL){
    // ...
    char *string_field_in_read_line_p = strtok(read_line_p, "\n");
    char *integer_field_in_read_line_p = strtok(NULL, "\n");

fgets函数读取一行'\n',并在其末尾留下换行符。这意味着您尝试标记的字符串中只有一个。 '\n'所以第二次调用strtok应该返回NULL

您不会对此进行检查,因此对该NULL指针的任何取消引用(发生在转换函数中)都将导致未定义的行为和可能的崩溃。

于 2018-11-08T09:38:25.090 回答