Wrote a tree, checked in Valgrind:

==7266== Memcheck, a memory error detector ==7266== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==7266== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==7266== Command: ./lb2 ==7266== ! exit ==7266== ==7266== HEAP SUMMARY: ==7266== in use at exit: 8 bytes in 1 blocks ==7266== total heap usage: 2 allocs, 1 frees, 1,032 bytes allocated ==7266== ==7266== 8 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==7266== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==7266== by 0x108F37: AVL_Create (in /home/igor/lb2/lb2) ==7266== by 0x108BB6: InputFiller (in /home/igor/lb2/lb2) ==7266== by 0x108A8B: main (in /home/igor/lb2/lb2) ==7266== ==7266== LEAK SUMMARY: ==7266== definitely lost: 8 bytes in 1 blocks ==7266== indirectly lost: 0 bytes in 0 blocks ==7266== possibly lost: 0 bytes in 0 blocks ==7266== still reachable: 0 bytes in 0 blocks ==7266== suppressed: 0 bytes in 0 blocks ==7266== ==7266== For counts of detected and suppressed errors, rerun with: -v ==7266== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) 

Those. when I exit, I still have not unnamed memory! I can’t find an error:

main.c:

 /* БистСмныС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ */ #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <ctype.h> /* ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ */ #include "AVL_tree_slimrg.h" #include "settings_slimrg.h" /* Π‘ΠΈΠ³Π½Π°Ρ‚ΡƒΡ€Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ */ unsigned short int InputFiller(); // Π’Π²ΠΎΠ΄ ΠΈ исполнСниС ΠΊΠΎΠΌΠΌΠ°Π½Π΄ /* Основной Ρ†ΠΈΠΊΠ» */ int main(){ // ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ // Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ ΠΈ выполняСм ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ InputFiller(); // ΠŸΠ°ΡƒΠ·Π° ΠΏΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ if (debug_pauseonclose) system("pause"); // ВсС ОК return 0; } // Π¦ΠΈΠΊΠ» Π²Π²ΠΎΠ΄Π° ΠΈ выполнСния unsigned short int InputFiller(){ // ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ char tmpchar[StringLengthPS+1]; // Π’Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для символа char tmpword[StringLengthPS+1]; // Π’Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для слова (массива символов) unsigned long long int tmpkey; // Π’Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для ΠΊΠ»ΡŽΡ‡Π° unsigned int i; // Π’ΠΈΠΊΠ΅Ρ€ (для Ρ†ΠΈΠΊΠ»ΠΎΠ² ΠΈ Ρ‚.Π΄.) // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ пустого Π΄Π΅Ρ€Π΅Π²Π° struct avltree* AVLTree1 = AVL_Create(); // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ for (i = 0; i <= 256; i++) { tmpchar[i] = tmpword[i] = 0; } // Пока Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ - считываСм ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ символ строки while (scanf("%s", tmpchar) >= 1){ // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ Π² Π½ΠΈΠΆΠ½ΠΈΠΉ рСгистр tmpchar[0] = tolower(tmpchar[0]); // ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΌΠ°Π½Π΄Ρ‹ switch (tmpchar[0]) { // ΠžΡ‚Π»Π°Π΄ΠΎΡ‡Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΌΠ°Π½Π΄Ρ‹ case '!': // Π‘Ρ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ слово scanf("%s", tmpword); // ΠŸΠ΅Ρ€Π΅Π²ΠΎΠ΄ Π² Π½ΠΈΠΆΠ½ΠΈΠΉ рСгистр for (i = 0; i < StringLengthPS; i++) tmpword[i] = tolower(tmpword[i]); // РаспознаниС слова if (strcmp(tmpword, "exit") == 0) { return 0; } else if (strcmp(tmpword, "print") == 0) { AVL_PrintMe(AVLTree1); } break; } // Чистка for (i = 0; i <= 256; i++) { tmpchar[i] = tmpword[i] = 0; } } // ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° памяти ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Ρ…ΠΎΠ΄ΠΎΠΌ AVL_FreeAndNil(AVLTree1); // ВсС ОК return 0; } 

And the library itself AVL_tree_slimrg.c:

 #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "AVL_tree_slimrg.h" // Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° строки struct String{ char* Text; unsigned short int count; }; // Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° листа struct avlleaf { struct String key; // ΠšΠ»ΡŽΡ‡ unsigned long long int llupar; // Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ long int height; // Высота struct avlleaf* left; // Π›Π΅Π²Ρ‹ΠΉ Ρ€Π΅Π±Π΅Π½ΠΎΠΊ struct avlleaf* right; // ΠŸΡ€Π°Π²Ρ‹ΠΉ Ρ€Π΅Π±Π΅Π½ΠΎΠΊ }; // Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π΄Π΅Ρ€Π΅Π²Π° struct avltree { struct avlleaf* root; }; // Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π΄Π΅Ρ€Π΅Π²Π° struct avltree* AVL_Create() { struct avltree* AVL_Tree = malloc(sizeof(struct avltree)); AVL_Tree->root = NULL; return AVL_Tree; } // Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Π΅Ρ€Π΅Π²Π° void AVL_FreeAndNil(struct avltree* AVL_Tree) { // ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ char tmpword[StringLengthPS+1]; unsigned short int i; // Π’ΠΈΠΊΠ΅Ρ€ (для Ρ†ΠΈΠΊΠ»ΠΎΠ² ΠΈ Ρ‚.Π΄.) // ЗапускаСм Π±Π°Π»Π°Π»Π°ΠΉΠΊΡƒ ^_^ while (AVL_IsEmpty(AVL_Tree) == false) { for (i = 0; i <= AVL_Tree->root->key.count; i++) { tmpword[i] = AVL_Tree->root->key.Text[i]; } AVL_RemoveLeaf(tmpword, AVL_Tree, false); } } // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° пустоту bool AVL_IsEmpty(struct avltree* AVL_Tree) { return (AVL_Tree->root == NULL); } // РСбалансировка Π΄Π΅Ρ€Π΅Π²Π° struct avlleaf* AVL_BalanceMe(struct avlleaf* Leaf) { // ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ char balfac; // ΠšΠΎΡΡ„Ρ„ΠΈΡ†Π΅Π½Ρ‚ баласировки (ΠΎΡ‚ -2 Π΄ΠΎ +2) balfac = AVLLeaf_GetBalance(Leaf); // ΠžΡ†Π΅Π½ΠΈΠ²Π°Π΅ΠΌ баланс ΠΈ выправляСм Π΅Π³ΠΎ if (balfac < -1) { // Π‘ΠΌΠΎΡ‚Ρ€ΠΈΠΌ, трСбуСтся Π»ΠΈ большоС Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ if (AVLLeaf_GetBalance(Leaf->left) > 0) { Leaf->left = AVL_rotation_SL(Leaf->left); } return (AVL_rotation_SR(Leaf)); } else if (balfac > 1) { // Π‘ΠΌΠΎΡ‚Ρ€ΠΈΠΌ, трСбуСтся Π»ΠΈ большоС Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ if (AVLLeaf_GetBalance(Leaf->right) < 0) { Leaf->right = AVL_rotation_SR(Leaf->right); } return (AVL_rotation_SL(Leaf)); } else { // Если Π½ΡƒΠ»ΡŒ // Π’Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ НЕ трСбуСтся AVLLeaf_CheckHeight(Leaf); return Leaf; } } / Поиск ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ struct avlleaf* AVL_FindAndRemove(char key[StringLengthPS+1], struct avlleaf* Leaf, bool PrintStatus) { // ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ struct avlleaf* child; // БлуТСбная (для случаСв с ΠΎΠ΄Π½ΠΈΠΌ Ρ€Π΅Π±Π΅Π½ΠΊΠΎΠΌ) struct String tmpstring; // Π‘Ρ‚Ρ€ΠΎΠΊΠ° char* tmpkey; // Π’Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для ΠΊΠ»ΡŽΡ‡Π° unsigned short int i; // Π’ΠΈΠΊΠ΅Ρ€ (для Ρ†ΠΈΠΊΠ»ΠΎΠ² ΠΈ Ρ‚.Π΄.) int debug; // Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ сравнСния строк [BUG] if (Leaf != NULL) debug = strcmp(key, Leaf->key.Text); if (Leaf == NULL) { // НСт значСния для удалСния if (PrintStatus) printf("NoSuchWord\n"); return NULL; } else if (debug < 0) { Leaf->left = AVL_FindAndRemove(key, Leaf->left, PrintStatus); return AVL_BalanceMe(Leaf); } else if (debug > 0) { Leaf->right = AVL_FindAndRemove(key, Leaf->right, PrintStatus); return AVL_BalanceMe(Leaf); } else { // НайдСна позиция // Анализ Π΄Π΅Ρ‚Π΅ΠΉ ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ if (Leaf->left != NULL && Leaf->right != NULL) { // ΠžΡ‡ΠΈΡΡ‚ΠΊΠ° ΠΈ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° free(Leaf->key.Text); Leaf->key.count = 0; // Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π΅Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹ tmpstring = AVL_GetMinKey(Leaf->right); tmpkey = (char*)malloc((StringLengthPS+1)*sizeof(char)); // ΠŸΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Leaf->llupar = AVL_GetMinVal(Leaf->right); Leaf->key.count = tmpstring.count; // ΠŸΠ΅Ρ€Π΅Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти Leaf->key.Text = (char*)malloc((Leaf->key.count+1) * sizeof(char)); // ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ тСкста... for (i = 0; i <= Leaf->key.count; i++) { Leaf->key.Text[i] = tmpkey[i] = tmpstring.Text[i]; } // Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ дубля Leaf->right = AVL_FindAndRemove(tmpkey, Leaf->right, PrintStatus); // ОсвобоТдСниС памяти free(tmpkey); // Балансировка return AVL_BalanceMe(Leaf); } else if (Leaf->left != NULL) { // Π•ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π΅Π±Π΅Π½ΠΎΠΊ (ΠΏΡ€Π°Π²Ρ‹ΠΉ) if (PrintStatus) printf("OK\n"); // НаслСдованиС child = Leaf->left; // ОсвобоТдСниС памяти Leaf->key.count = 0; free(Leaf->key.Text); free(Leaf); // Π’ΠΎΠ·Ρ€Π°Ρ‚ Ρ€Π΅Π±Π΅Π½ΠΊΠ° return child; } else if (Leaf->right != NULL) { // Π•ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π΅Π±Π΅Π½ΠΎΠΊ (Π»Π΅Π²Ρ‹ΠΉ) if (PrintStatus) printf("OK\n"); // НаслСдованиС child = Leaf->right; // ОсвобоТдСниС памяти Leaf->key.count = 0; free(Leaf->key.Text); free(Leaf); // Π’ΠΎΠ·Ρ€Π°Ρ‚ Ρ€Π΅Π±Π΅Π½ΠΊΠ° return child; } else { // НСт Π΄ΠΈΡ‚Π΅ΠΉ - просто Π²Ρ‹ΠΊΠΈΠ΄Ρ‹Π²Π°Π΅ΠΌ if (PrintStatus) printf("OK\n"); Leaf->key.count = 0; free(Leaf->key.Text); free(Leaf); return NULL; } } } 

1 answer 1

Right here

 if (strcmp(tmpword, "exit") == 0) { return 0; } 

will exit the InputFiller function without freeing AVLTree1 .

  • Oh, I missed Thank you, but I sinned at the library library - Alrott SlimRG