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; } } }