Ошибка вывода и выделения памяти в Си

Я работаю с wchar_t, моя задача - распечатать предложения из текста, которые являются анаграммами друг для друга. Для реализации текста необходимо использовать структуры Текст и Предложение. Ошибка заключается в том, что после 1-2 выводов анаграммных предложений, программа еще немного "думает" и завершает работу без каких-либо предупреждений и ошибок, но анаграммы она выводит не все и через раз меняется количество выводимых анаграмм в одном и том же тексте.

Вот сами структуры и функции, чтобы вы не заходили в ступор, в случае чего, я сделал достаточно много комментариев. Надеюсь, все будет понятно.

// Введем новый тип данных - структуру "Sentece", хранящую наше предложение и количество символов в нем,
// а так же флаг, показывающий, является ли наше предложение анаграммой для какого либо из остальных
// предложений текста. Последнее поле - количество заглавных букв в предложении.
struct Sentence {
    wchar_t* sentence_text;
    size_t sentence_size;   
    bool is_sentence_anagram;
    int64_t capital_letters_quant;
};

// Введем новый тип данных - структуру "Text", хранящую наш текст и количество предложений в нем.
struct Text {
    struct Sentence* full_text;
    size_t full_text_size;
};

// Определим функцию, что печатает все предложения, являющиеся анаграммами друг для друга.
void print_anagram_sentences(struct Text processed_text) {
    // Идея такова: мы проходимся по массиву предложений и каждое i-е предложение
    // сравниваем со всеми последующими, если при сравнении мы выяснили, что эти
    // предложения - анаграммы, печатаем их. Как выяснять анаграммы ли предложения?
    // Для выяснения мы просто будем создавать новые предложения, в которые будем
    // записывать все символы исходного предложения, если эти символы - буквы или цифры.
    // Далее выполняем лексикографическую сортировку наших предложений и сравниваем.
    // Вот и все, если отсортированные предложения равны, то они - анаграммы, иначе, нет.

    // Для начала войдем во внешний цикл сравнения.
    for (size_t i = 0; i < processed_text.full_text_size - 1 && !processed_text.full_text[i].is_sentence_anagram; i++) {
        // Создадим новое предложение.
        struct Sentence first_current_sentence = {(wchar_t*) malloc(processed_text.full_text[i].sentence_size * sizeof(wchar_t)), 0, false, 0};

        // Теперь присвоим нашему массиву символов (тексту нашего предложения) все значения исходного предложения, если
        // они - буквы или цифры.
        for (size_t k = 0; k < processed_text.full_text[i].sentence_size; k++) {
            if (iswalpha(processed_text.full_text[i].sentence_text[k]) || iswdigit(processed_text.full_text[i].sentence_text[k])) {
                first_current_sentence.sentence_text[first_current_sentence.sentence_size] = towlower(processed_text.full_text[i].sentence_text[k]);
                first_current_sentence.sentence_size++;
            }
        }

        // Закончим ввод и добавим в конец нуль-терминатор.
        first_current_sentence.sentence_text[first_current_sentence.sentence_size] = L'\0';

        // Выполним лексикографическую сортировку текста предложения для дальнейшего сравнения.
        qsort(first_current_sentence.sentence_text, first_current_sentence.sentence_size, sizeof(wchar_t), first_compare);

        // Начинаем внутренний цикл пробежек.
        for(size_t j = i + 1; j < processed_text.full_text_size; j++) {
            // Создадим новое предложение.
            struct Sentence second_current_sentence = {(wchar_t*) malloc(processed_text.full_text[j].sentence_size * sizeof(wchar_t)), 0, false, 0};

            // Теперь присвоим нашему массиву символов (тексту нашего предложения) все значения исходного предложения, если
            // они - буквы или цифры.
            for (size_t k = 0; k < processed_text.full_text[j].sentence_size; k++) {
                if (iswalpha(processed_text.full_text[j].sentence_text[k]) || iswdigit(processed_text.full_text[j].sentence_text[k])) {
                    second_current_sentence.sentence_text[second_current_sentence.sentence_size] = towlower(processed_text.full_text[j].sentence_text[k]);
                    second_current_sentence.sentence_size++;
                }
            }

            // Закончим ввод и добавим в конец нуль-терминатор.
            second_current_sentence.sentence_text[second_current_sentence.sentence_size] = L'\0';

            // Выполним лексикографическую сортировку текста предложения для дальнейшего сравнения.
            qsort(second_current_sentence.sentence_text, second_current_sentence.sentence_size, sizeof(wchar_t), first_compare);

            // Теперь мы сравниваем наши предложения.
            // Во-первых, если они уже печатались, то второй раз нам этого делать не нужно, для этого используется флаг is_sentence_anagram у
            // каждого предложения. Во-вторых, мы проверяем, равны ли наши отсортированные предложения.
            if (!wcscmp(first_current_sentence.sentence_text, second_current_sentence.sentence_text)) {
                // Если они оказались равны, мы проверяем, является ли уже наше внешнее предложения анаграммой дабы ненароком не
                // распечатать его еще раз. После проверки печатаем нужные предложения . заканчиваем цикл присвоением значения
                // true флагу внутреннего предложения, чтоба потом не распечатывать его.
                wprintf(L"[");
                print_sentence(processed_text.full_text[i]);
                wprintf(L"] | [");
                print_sentence(processed_text.full_text[j]);
                wprintf(L"]");

                processed_text.full_text[i].is_sentence_anagram = true;
                processed_text.full_text[j].is_sentence_anagram = true;

                wprintf(L"\n");
            }

            // Освободим выделенную ранее под предложения память, чтобы позже зарезервировать новую.
            free(second_current_sentence.sentence_text);
        }

        // Освободим выделенную ранее под предложения память, чтобы позже зарезервировать новую.
        free(first_current_sentence.sentence_text);
    }
}

// Определим первую функцию-компаратор для сортировки какой-либо строки методом qsort().
int first_compare(const void *first_current_symbol, const void *second_current_symbol) {
    wchar_t* compare_first_current_symbol = (wchar_t*) first_current_symbol;
    wchar_t* compare_second_current_symbol = (wchar_t*) second_current_symbol;

    if (*compare_first_current_symbol > *compare_second_current_symbol) {
        return 1;
    }

    if (*compare_first_current_symbol < *compare_second_current_symbol) {
        return -1;
    }

    return 0;
}

То есть буквально для текста "Привет. Это начало текста. Тут круто. Нет. Почему. Ктут руто. Это ДЛЯ анаГРАММЫы было. А это для повтора. Что. БА БАБАБ. Круть. БАБ АБАБ."

Моя программа в итоге печатает лишь "[ Тут круто.] | [ Ктут руто.]"


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