Неожиданное завершение программы в Qt при попытке отобразить файл csv

Не судите строго, это лабораторная работа...

Мне нужно разработать на Qt программу для визуализации табличных данных и вычисления по ним статистических метрик. По нажатию на кнопку "Load data" данные из файла должны быть загружены. В таблице должны отобразиться данные. В результате считывания файла должно быть отображено информационное окно с общим количеством строк в файле, количеством строк содержащих ошибку и количеством успешно считанных строк. В таблице должны быть отображены только те структуры, строки которых, не содержат пустых полей или ошибок в полях. Но при нажатии на кнопку load data происходит неожиданное завершение программы, причем данные считываются в list вроде бы корректно.

Код в mainwindow.cpp:

void MainWindow::onPushButtonLoadDataClicked() {
    AppParams params;
    params.filename = allocateString(context.filename);
    doOperation(Validate, &context, &params);
    if (context.fileStatus) {
        doOperation(LoadData, &context, &params);
        displayDataInTable();

        QMessageBox::information(this, "Information", "Count of lines: " + QString::number(context.lines) + "\nSuccess read: " + QString::number(context.successRead) + "\nFailed read: " + QString::number(context.failedRead));
    }
    else
        QMessageBox::critical(this, "ERROR", "Error");
    freeString(params.filename);
}

void MainWindow::displayDataInTable() {
    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(7);
    ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("year"));
    ui->tableWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("region"));
    ui->tableWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("npg"));
    ui->tableWidget->setHorizontalHeaderItem(3, new QTableWidgetItem("birth_rate"));
    ui->tableWidget->setHorizontalHeaderItem(4, new QTableWidgetItem("death_rate"));
    ui->tableWidget->setHorizontalHeaderItem(5, new QTableWidgetItem("gdw"));
    ui->tableWidget->setHorizontalHeaderItem(6, new QTableWidgetItem("urbanization"));
    int i = 0;
    for (Iterator it = context.begin; it.current != context.end.current; next(&it)) {
        for (int j = 0; j < 7; j++) {
            ui->tableWidget->setItem(i, j, new QTableWidgetItem(QString::fromLatin1(it.current->data->values[j])));
        }
        i++;
    }
}

тут считывается файл


typedef struct CsvReadResult {
    List* list;
    int linesNum;
    int successReadNum;
    int failedReadNum;
} CsvFileReadResult ;

int getValuesNum(char* source) {
    int result = 1;
    for (size_t i = 0; i < strlen(source); i++) {
        if (source[i] == ',')
            result++;
    }
    return result;
}

char** getArrayBySeparator(char* source) {
    char** arr = createArrayOfStrings(getValuesNum(source));
    char* buffer = allocateString("");
    int current = 0;
    size_t bufferLength = 0;
    for (size_t i = 0; i < strlen(source); i++) {
        if (source[i] == ',') {
            arr[current] = buffer;
            buffer = allocateString("");
            bufferLength = 0;
            current++;
        }
        else {
            if (source[i] != '\n') {
                int newLength = bufferLength + 1;
                char* newBuffer = (char*)realloc(buffer, newLength + 1);
                if (newBuffer != NULL) {
                    buffer = newBuffer;
                    buffer[bufferLength] = source[i];
                    buffer[bufferLength + 1] = '\0';
                    bufferLength++;
                }
            }
        }
    }
    arr[current] = buffer;
    return arr;
}

int validateRecord(CsvRecord* record) {
    int result = SUCCESS;
    int count = 7;
    if (record->valuesNum != count)
        result = ERROR;
    else {
        int readStatus = 0;
        double temp;
        readStatus += sscanf(record->values[2], "%lf", &temp);
        readStatus += sscanf(record->values[3], "%lf", &temp);
        readStatus += sscanf(record->values[4], "%lf", &temp);
        readStatus += sscanf(record->values[5], "%lf", &temp);
        readStatus += sscanf(record->values[6], "%lf", &temp);
        if (readStatus != count - 2)
            result = ERROR;
    }
    return result;
}

int csvReadHeader(CsvRecord* dest, char* filename) {
    int result = SUCCESS;
    if (dest != NULL) {
        FILE* file = fopen(filename, "r");
        if (file != NULL) {
            char* buffer = (char*)calloc(MAX_LEN, sizeof(char));
            fgets(buffer, MAX_LEN, file);
            fclose(file);
            buffer[strlen(buffer) - 1] = '\0';
            char* bufferString = allocateString(buffer);
            int count = getValuesNum(bufferString);
            char** arrayOfValues = getArrayBySeparator(bufferString);
            dest->valuesNum = count;
            dest->values = arrayOfValues;
            freeString(bufferString);
            free(buffer);
        }
    } else {
        result = ERROR;
    }
    return result;
}

CsvReadResult* readResult(char* filename, char* region) {
    CsvReadResult* result = NULL;
    CsvRecord* header = allocateCsvRecord();
    csvReadHeader(header, filename);
    FILE* file = fopen(filename, "r");
    if (file!=NULL) {
        result = (CsvReadResult*)calloc(1, sizeof(CsvReadResult));
        result->linesNum = -1;
        result->failedReadNum = -1;
        result->successReadNum = -1;
        result->list = createList(header);
        char* buffer = (char*)calloc(MAX_LEN, sizeof(char));
        while (!feof(file)) {
            result->linesNum++;
            fgets(buffer, MAX_LEN, file);
            char* bufferString = allocateString(buffer);
            CsvRecord* currentRecord = allocateCsvRecord();
            currentRecord->valuesNum = getValuesNum(bufferString);
            currentRecord->values = getArrayBySeparator(bufferString);
            if (validateRecord(currentRecord)==SUCCESS) {
                currentRecord->active = 1;
                result->successReadNum++;
                if (region == NULL) {
                    listPushBack(result->list, currentRecord);
                }
                else if (!stringCmp(currentRecord->values[1], region))
                    listPushBack(result->list, currentRecord);
                else
                    freeCsvRecord(currentRecord);
            }
            else {
                result->failedReadNum++;
                freeArrayOfStrings(currentRecord->values, currentRecord->valuesNum);
                freeCsvRecord(currentRecord);
            }
            freeString(bufferString);
        }
        free(buffer);
        fclose(file);
    }
    else
        freeArrayOfStrings(header->values, header->valuesNum);
    return result;
}

list:

typedef struct CsvRecord{
    char** values;
    int valuesNum;
    int active;
} CsvRecord;

typedef struct Node {
    CsvRecord* data;
    struct Node* next;
} Node;

typedef struct List {
    Node* first;
} List;

typedef  struct Iterator {
    Node* current;
} Iterator;

CsvRecord* allocateCsvRecord() {
    CsvRecord* result = NULL;
    result = (CsvRecord*)calloc(1, sizeof(CsvRecord));

    return result;
}

void freeCsvRecord(CsvRecord* record) {
    free(record);
}

List* createList(CsvRecord* record) {
    List* result = (List*)calloc(1, sizeof(List));
    Node* startNode = (Node*)calloc(1, sizeof(Node));
    startNode->data = record;
    startNode->next = NULL;
    result->first = startNode;
    return result;
}

void listPushBack(List* list, CsvRecord* record) {
    Node* last = list->first;
    while (last->next) {
        last = last->next;
    }
    Node* tmp = (Node*)calloc(1, sizeof(Node));
    tmp->data = record;
    tmp->next = NULL;
    last->next = tmp;
}

void freeList(List* list) {
    Node* p = list->first;
    while (p != NULL) {
        Node* next = p->next;
        freeArrayOfStrings(p->data->values, p->data->valuesNum);
        freeCsvRecord(p->data);
        free(p);
        p = next;
    }
    free(list);
}

Iterator beginActive(List* list) {
    Iterator iterator;
    Node* firstActive = NULL;
    if (list != NULL) {
        Node* p = list->first;
        while (p->next) {
            if (p->data->active) {
                firstActive = p;
                break;
            }
            p = p->next;
        }
    }
    if (firstActive != NULL) {
        iterator.current = firstActive;
    }
    return iterator;
}

Iterator endActive(List* list) {
    Iterator iterator;
    Node* lastActive = NULL;
    Node* p = list->first;
    while (p != NULL) {
        if (p->data->active == 1) {
            lastActive = p;
        }
        p = p->next;
    }
    iterator.current = lastActive;
    return iterator;
}

void next(Iterator* it) {
    it->current = it->current->next;
}

Ответы (0 шт):