Ошибка вывода и выделения памяти в Си
Я работаю с 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;
}
То есть буквально для текста "Привет. Это начало текста. Тут круто. Нет. Почему. Ктут руто. Это ДЛЯ анаГРАММЫы было. А это для повтора. Что. БА БАБАБ. Круть. БАБ АБАБ."
Моя программа в итоге печатает лишь "[ Тут круто.] | [ Ктут руто.]"