From e5ada61339da7b9ea191d1fa45197b1b86d1014c Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Mon, 14 Feb 2022 17:16:58 +0300 Subject: [PATCH] fixed memory leak in Autoarr --- DtsodC/Makefile | 11 ++-- DtsodC/src/Autoarr/Autoarr.c | 32 +++++++---- DtsodC/src/Hashtable/hash.c | 6 +- DtsodC/src/SearchTree/SearchTree.c | 47 +++++++++------- DtsodC/src/base/types.c | 6 +- DtsodC/src/base/types.h | 2 +- DtsodC/src/main.c | 22 +------- DtsodC/src/tests/test_all.c | 7 --- DtsodC/src/tests/test_autoarr.c | 1 - DtsodC/src/tests/test_searchtree.c | 89 ++++++++++++++++-------------- DtsodC/src/tests/tests.c | 35 ++++++++++++ 11 files changed, 145 insertions(+), 113 deletions(-) delete mode 100644 DtsodC/src/tests/test_all.c create mode 100644 DtsodC/src/tests/tests.c diff --git a/DtsodC/Makefile b/DtsodC/Makefile index 42db5e5..ba77c07 100644 --- a/DtsodC/Makefile +++ b/DtsodC/Makefile @@ -1,6 +1,6 @@ SRC=$(wildcard src/*c) $(wildcard src/**/*.c) OUTDIR=bin/ -OUTFILE=dtsodc.com +OUTFILE=$(OUTDIR)dtsodc.com CMP=gcc all: clear_c build test @@ -14,10 +14,13 @@ clear_bin: clang: CMP=clang clang: all -CMPARGS=-O -static +CMPARGS=-O0 -g -Wall -Werror build: @echo "\e[36m-------------[build]---------------\e[0m" - $(CMP) $(CMPARGS) $(SRC) -o $(OUTDIR)$(OUTFILE) + $(CMP) $(CMPARGS) $(SRC) -o $(OUTFILE) test: @echo "\e[36m-------------[test]----------------\e[0m" - $(OUTDIR)$(OUTFILE) + $(OUTFILE) +valgrind: clear_c build + @echo "\e[36m-----------[valgrind]--------------\e[0m" + valgrind -s --read-var-info=yes --fullpath-after=DtsodC/ $(OUTFILE) \ No newline at end of file diff --git a/DtsodC/src/Autoarr/Autoarr.c b/DtsodC/src/Autoarr/Autoarr.c index cadad0f..bb5bc85 100644 --- a/DtsodC/src/Autoarr/Autoarr.c +++ b/DtsodC/src/Autoarr/Autoarr.c @@ -9,7 +9,7 @@ Autoarr Autoarr_create(uint16 _max_block_count, uint16 _max_block_length, my_typ .curr_block_length=0, .max_length=_max_block_count*_max_block_length, .curr_length=0, - .values=malloc(_max_block_count*typesize(_type)) + .values=malloc(_max_block_count*sizeof(void*)) }; *ar.values=malloc(_max_block_length*typesize(ar.type)); printf("%p %p\n",ar.values, *ar.values); @@ -20,7 +20,7 @@ Autoarr Autoarr_create(uint16 _max_block_count, uint16 _max_block_length, my_typ void __Autoarr_create_block(Autoarr *ar){ if (ar->curr_block_count>=ar->max_block_count) throw(ERR_MAXLENGTH); ar->curr_block_length=0; - *(ar->values+ar->curr_block_count)=malloc(ar->max_block_length*typesize(ar->type)); + ar->values[ar->curr_block_count]=malloc(ar->max_block_length*typesize(ar->type)); ar->curr_block_count++; } @@ -159,29 +159,39 @@ void Autoarr_clear(Autoarr* ar){ switch (ar->type) { case Int8: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((int8**)ar->values+i)); break; + free((int8*)ar->values[i]); + break; case UInt8: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((uint8**)ar->values+i)); break; + free((uint8*)ar->values[i]); + break; case Int16: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((int16**)ar->values+i)); break; + free((int16*)ar->values[i]); + break; case UInt16: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((uint16**)ar->values+i)); break; + free((uint16*)ar->values[i]); + break; case Int32: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((int32**)ar->values+i)); break; + free((int32*)ar->values[i]); + break; case UInt32: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((uint32**)ar->values+i)); break; + free((uint32*)ar->values[i]); + break; case Int64: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((int64**)ar->values+i)); break; + free((int64*)ar->values[i]); + break; case UInt64: for(uint16 i = 0; i < ar->curr_block_count;i++) - free(*((uint64**)ar->values+i)); break; - default: throw(ERR_WRONGTYPE); break; + free((uint64*)ar->values[i]); + break; + default: + throw(ERR_WRONGTYPE); + break; } free(ar->values); ar->type=Null; diff --git a/DtsodC/src/Hashtable/hash.c b/DtsodC/src/Hashtable/hash.c index 916477a..42e2c25 100644 --- a/DtsodC/src/Hashtable/hash.c +++ b/DtsodC/src/Hashtable/hash.c @@ -2,16 +2,14 @@ uint32 ihash(char *str){ uint32 hash=5381; - char c; - while(c=*(str++)) + for (char c=*str;c;c=*(++str)) hash=((hash<<5)+hash)+c; //hash=hash*33^c return hash; } uint64 lhash(char* str){ uint64 hash = 0; - int c; - while (c=*(str++)) + for (char c=*str;c;c=*(++str)) hash=c+(hash<<6)+(hash<<16)-hash; return hash; } diff --git a/DtsodC/src/SearchTree/SearchTree.c b/DtsodC/src/SearchTree/SearchTree.c index 417ba8e..3e23483 100644 --- a/DtsodC/src/SearchTree/SearchTree.c +++ b/DtsodC/src/SearchTree/SearchTree.c @@ -1,5 +1,4 @@ #include "SearchTree.h" - #include "../tests/tests.h" STNode* STNode_create(){ STNode* node=malloc(sizeof(STNode)); @@ -9,8 +8,7 @@ STNode* STNode_create(){ return node; } -uint8 nodn=0; -void STNode_free(STNode* node){dbg(0);nodn++; +void STNode_free(STNode* node){ if (!node) throw(ERR_NULLPTR); if(node->branches){ for(uint8 n32 = 0;n32<8;n32++){ @@ -31,12 +29,26 @@ void STNode_free(STNode* node){dbg(0);nodn++; } } free(node->branches); - }dbg(1); - //if value is not freed ptr - if(node->value.type>12 && node->value.type<21 && node->value.VoidPtr) - free(node->value.VoidPtr);dbg(2);printf("nodn %u\n",nodn); - printstnode(node); - free(node);dbg(3);nodn--; + } + if(node->value.VoidPtr) + switch (node->value.type) { + case Int8Ptr: case UInt8Ptr: + case Int16Ptr: case UInt16Ptr: + case Int32Ptr: case UInt32Ptr: + case Int64Ptr: case UInt64Ptr: + free(node->value.VoidPtr); + break; + case AutoarrPtr: + Autoarr_clear((Autoarr*)node->value.VoidPtr); + free(node->value.VoidPtr); + break; + case STNodePtr: + STNode_free((STNode*)node->value.VoidPtr); + break; + default: // value is not ptr + break; + } + free(node); } typedef struct {uint8 n32, n4, rem;} indexes3; @@ -51,10 +63,9 @@ indexes3 splitindex(uint8 i){ void ST_push(STNode* node_first, const char* key, Unitype value){ if (!node_first) throw(ERR_NULLPTR); - char c=*(key++); STNode* node_last=node_first; - while(c){ - indexes3 i3=splitindex((uint8)c); + while(*key){ + indexes3 i3=splitindex((uint8)*key); if(!node_last->branches){ node_last->branches=(STNode****)malloc(8*sizeof(STNode*)); for(uint8 i=0;i<8;i++) @@ -69,24 +80,22 @@ void ST_push(STNode* node_first, const char* key, Unitype value){ node_last->branches[i3.n32][i3.n4]=(STNode**)malloc(4*sizeof(STNode*)); for(uint8 i=0;i<4;i++) node_last->branches[i3.n32][i3.n4][i]=(STNode*)NULL; - node_last->branches[i3.n32][i3.n4]=node_last->branches[i3.n32][i3.n4]; } if(!node_last->branches[i3.n32][i3.n4][i3.rem]) node_last->branches[i3.n32][i3.n4][i3.rem]=STNode_create(); node_last=node_last->branches[i3.n32][i3.n4][i3.rem]; - c=*(key++); + key++; } node_last->value=value; } -const Unitype UnitypeNull={Null,.VoidPtr=NULL}; +const Unitype UnitypeNull={.type=Null,.VoidPtr=NULL}; Unitype ST_pull(STNode* node_first, const char* key){ if (!node_first) throw(ERR_NULLPTR); - char c = *key; STNode* node_last=node_first; - for (uint16 i=0;c!='\0';){ - indexes3 i3=splitindex((uint8)c); + while (*key){ + indexes3 i3=splitindex((uint8)*key); if(!node_last->branches) return UnitypeNull; STNode*** ptrn32=(STNode***)node_last->branches[i3.n32]; if(!ptrn32) return UnitypeNull; @@ -94,7 +103,7 @@ Unitype ST_pull(STNode* node_first, const char* key){ if(!ptrn4) return UnitypeNull; node_last=ptrn4[i3.rem]; if(!node_last) return UnitypeNull; - c=*(key+(++i)); + key++; } return node_last->value; } diff --git a/DtsodC/src/base/types.c b/DtsodC/src/base/types.c index fe4bfac..212ab2d 100644 --- a/DtsodC/src/base/types.c +++ b/DtsodC/src/base/types.c @@ -26,7 +26,7 @@ const char* typename(my_type t){ case Int64Ptr: return "Int64Ptr"; case UInt64Ptr: return "UInt64Ptr"; case UniversalType: return "Unitype"; - default: throw(ERR_WRONGTYPE); + default: throw(ERR_WRONGTYPE); return "ERROR"; } } @@ -35,7 +35,7 @@ int8 typesize(my_type type){ case Null: return 0; case Double: return sizeof(double); case Float: return sizeof(float); - case Bool: sizeof(bool); + case Bool: return sizeof(bool); case Char: case Int8: case UInt8: return 1; @@ -54,6 +54,6 @@ int8 typesize(my_type type){ case Int64Ptr: case UInt64Ptr: return sizeof(void*); case UniversalType: return "Unitype"; - default: throw(ERR_WRONGTYPE); + default: throw(ERR_WRONGTYPE); return -1; } } diff --git a/DtsodC/src/base/types.h b/DtsodC/src/base/types.h index fb838a8..f0742e3 100644 --- a/DtsodC/src/base/types.h +++ b/DtsodC/src/base/types.h @@ -15,7 +15,7 @@ typedef enum my_type{ Null, Float, Double, Char, Bool, UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64, UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr, - UniversalType + UniversalType, AutoarrPtr, STNodePtr } __attribute__ ((__packed__)) my_type; //returns type name diff --git a/DtsodC/src/main.c b/DtsodC/src/main.c index 547b59d..f8596b1 100644 --- a/DtsodC/src/main.c +++ b/DtsodC/src/main.c @@ -7,26 +7,6 @@ int main(){ setlocale(LC_ALL, "en-US.Unicode"); printf("\e[92mdtsod parser in c language!\e[97m\n"); - /*test_all(); - Unitype a={Double,.Double=9}; - STNode* node=STNode_create(); - ST_push(node,"type", a); - ST_push(node,"time", a); - ST_push(node,"author_id", a); - ST_push(node,"channel_id", a); - ST_push(node,"message_id", a); - ST_push(node,"text", a); - ST_push(node,"files", a); - a=ST_pull(node,""); - STNode_free(node); - printf("%u\n", ihash("0")); - printf("%lu\n", lhash("0")); - printf("%u\n", ihash("1kakdkale210r")); - printf("%lu\n", lhash("1kakdkale210r"));*/ - int** ptr2=NULL; - int a=4; - int* ptr=&a; - ptr2=&ptr; - printf("%p %p",ptr2, *ptr2); + test_all(); return 0; } diff --git a/DtsodC/src/tests/test_all.c b/DtsodC/src/tests/test_all.c deleted file mode 100644 index bccdd60..0000000 --- a/DtsodC/src/tests/test_all.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tests.h" - -void test_all(void){ - test_autoarr(); - test_searchtree(); - printf("\e[96m---------------------------------------\n"); -} \ No newline at end of file diff --git a/DtsodC/src/tests/test_autoarr.c b/DtsodC/src/tests/test_autoarr.c index 64a2070..83e5a89 100644 --- a/DtsodC/src/tests/test_autoarr.c +++ b/DtsodC/src/tests/test_autoarr.c @@ -38,7 +38,6 @@ void test_autoarr(){ printallval(&ar); printf("\n\e[92mautoarr filled up\n"); printautoarr(&ar); - printf("%p %p\n",ar.values, *ar.values); Autoarr_clear(&ar); printf("\e[92mautoarr cleared\n"); } diff --git a/DtsodC/src/tests/test_searchtree.c b/DtsodC/src/tests/test_searchtree.c index ffadbef..4d402dd 100644 --- a/DtsodC/src/tests/test_searchtree.c +++ b/DtsodC/src/tests/test_searchtree.c @@ -1,33 +1,6 @@ #include "tests.h" #include "../SearchTree/SearchTree.h" -void printuni(Unitype v){ - switch (v.type) { - case Null: printf("{%s}",typename(v.type));break; - case Double: printf("{%s:%lf}",typename(v.type),v.Double);break; - case Float: printf("{%s:%f}",typename(v.type),v.Float);break; - case Char: printf("{%s:%c}",typename(v.type),v.Int8);break; - case UInt8: - case UInt16: printf("{%s:%u}",typename(v.type),v.UInt16);break; - case UInt32: - case UInt64: printf("{%s:%lu}",typename(v.type),v.UInt64);break; - case Bool: - case Int8: - case Int16: printf("{%s:%d}",typename(v.type),v.Int16);break; - case Int32: - case Int64: printf("{%s:%ld}",typename(v.type),v.Int64);break; - case Int8Ptr: - case UInt8Ptr: - case Int16Ptr: - case UInt16Ptr: - case Int32Ptr: - case UInt32Ptr: - case Int64Ptr: - case UInt64Ptr: printf("{%s:%p}",typename(v.type),v.VoidPtr);break; - default: throw(ERR_WRONGTYPE);break; - } -} - void printstnode(STNode* node){ printf("\e[94mSTNode: %lu\n address: %p\n value: ",sizeof(STNode),node); printuni(node->value); @@ -35,14 +8,14 @@ void printstnode(STNode* node){ printf("\n branches: %p\n", node->branches); if(node->branches) for(uint8 i=0;i<8;i++){ printf(" \e[90m[%u]=%p\n",i,node->branches[i]); - for (uint8 ii = 0; ii < 8; ii++){ - if(node->branches[i]){ - printf(" \e[90m[%u]=%p\n",ii,node->branches[i][ii]); - for (uint8 iii = 0; iii < 4; iii++) - if(node->branches[i][ii]) - printf(" \e[90m[%u]=%p\n",iii,node->branches[i][ii][iii]); - } - } + if(node->branches[i]) + for (uint8 ii = 0; ii < 8; ii++){ + printf(" \e[90m[%u]=%p\n",ii,node->branches[i][ii]); + if(node->branches[i][ii]) + for (uint8 iii = 0; iii < 4; iii++) + printf(" \e[90m[%u]=%p\n",iii,node->branches[i][ii][iii]); + } + } } @@ -50,14 +23,46 @@ void test_searchtree(){ printf("\e[96m-----------[test_searchtree]-----------\n"); STNode* node=STNode_create(); printf("\e[92mnode created\n"); - Unitype v={.type=Double,.Double=-9.22003}; - ST_push(node, "key_aa",v); - printuni(v); - printf(" -> push(key_aa)"); - v =ST_pull(node,"key_aa"); - printf("\npull(key_aa) -> "); - printuni(v); + printf("push:\e[94m\n "); + Unitype u={.type=Int16,.Int16=-3}; + printuni(u); + ST_push(node,"type", u); + printf(" -> type\n "); + u=(Unitype){.type=Int16,.Int16=25}; + printuni(u); + ST_push(node,"time", u); + printf(" -> time\n "); + u=(Unitype){.type=Double,.Double=-542.00600}; + printuni(u); + ST_push(node,"author_id", u); + printf(" -> author_id\n "); + u=(Unitype){.type=Int64,.Int64=-31255}; + printuni(u); + ST_push(node,"channel_id", u); + printf(" -> channel_id\n "); + u=(Unitype){.type=Float,.Float=32.2004}; + printuni(u); + ST_push(node,"message_id", u); + printf(" -> message_id\n "); + u=(Unitype){.type=Int8Ptr,.VoidPtr=malloc(1)}; + printuni(u); + ST_push(node,"text", u); + printf(" -> text\n"); + printf("\e[92mpull:\e[94m"); + printf("\n type -> "); + printuni(ST_pull(node,"type")); + printf("\n time -> "); + printuni(ST_pull(node,"time")); + printf("\n author_id -> "); + printuni(ST_pull(node,"author_id")); + printf("\n channel_id -> "); + printuni(ST_pull(node,"channel_id")); + printf("\n message_id -> "); + printuni(ST_pull(node,"message_id")); + printf("\n text -> "); + printuni(ST_pull(node,"text")); printf("\n"); + printf("\e[92mfirst node: "); printstnode(node); STNode_free(node); printf("\e[92mnode deleted\n"); diff --git a/DtsodC/src/tests/tests.c b/DtsodC/src/tests/tests.c new file mode 100644 index 0000000..c9301d3 --- /dev/null +++ b/DtsodC/src/tests/tests.c @@ -0,0 +1,35 @@ +#include "tests.h" + + +void printuni(Unitype v){ + switch (v.type) { + case Null: printf("{%s}",typename(v.type));break; + case Double: printf("{%s:%lf}",typename(v.type),v.Double);break; + case Float: printf("{%s:%f}",typename(v.type),v.Float);break; + case Char: printf("{%s:%c}",typename(v.type),v.Int8);break; + case UInt8: + case UInt16: printf("{%s:%u}",typename(v.type),v.UInt16);break; + case UInt32: + case UInt64: printf("{%s:%lu}",typename(v.type),v.UInt64);break; + case Bool: + case Int8: + case Int16: printf("{%s:%d}",typename(v.type),v.Int16);break; + case Int32: + case Int64: printf("{%s:%ld}",typename(v.type),v.Int64);break; + case Int8Ptr: + case UInt8Ptr: + case Int16Ptr: + case UInt16Ptr: + case Int32Ptr: + case UInt32Ptr: + case Int64Ptr: + case UInt64Ptr: printf("{%s:%p}",typename(v.type),v.VoidPtr);break; + default: throw(ERR_WRONGTYPE);break; + } +} + +void test_all(void){ + test_autoarr(); + test_searchtree(); + printf("\e[96m---------------------------------------\n"); +} \ No newline at end of file