Reputation: 11
Good evening forum, intrigued by potential memory leaks in the tool I'm writing in Ada95, I decided to run it with valgrind (valgrind-3.18.1). I'm using GNAT.Regpat for Regex support and I have compiled a series of regex patterns with it. I have 8 compiled regex patterns that result in a memory leak upon execution.
The command executed with valgrind is: valgrind --leak-check=full --show-leak-kinds=all ./main
.
Output received:
==8835== Memcheck, a memory error detector
==8835== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8835== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==8835== Command: ./main
==8835==
LT_ASSING
==8835== HEAP SUMMARY:
==8835== in use at exit: 552 bytes in 8 blocks
==8835== total heap usage: 12 allocs, 4 frees, 680 bytes allocated
==8835==
==8835== 28 bytes in 1 blocks are still reachable in loss record 1 of 8
==8835== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==8835== by 0x41F46E: __gnat_malloc (in /home/mg/Developing/Ada95/SF/obj/main)
==8835== by 0x405E88: sf_lexer___elabs (in /home/mg/Developing/Ada95/SF/obj/main)
==8835== by 0x4055B2: adainit (in /home/mg/Developing/Ada95/SF/obj/main)
==8835== by 0x405651: main (in /home/mg/Developing/Ada95/SF/obj/main)
==8835==
.
(6 entries practically identical to these two ↑ ↓)
.
==8835== 112 bytes in 1 blocks are still reachable in loss record 8 of 8
==8835== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==8835== by 0x41F46E: __gnat_malloc (in /home/mg/Developing/Ada95/SF/obj/main)
==8835== by 0x406224: sf_lexer___elabs (in /home/mg/Developing/Ada95/SF/obj/main)
==8835== by 0x4055B2: adainit (in /home/mg/Developing/Ada95/SF/obj/main)
==8835== by 0x405651: main (in /home/mg/Developing/Ada95/SF/obj/main)
==8835==
==8835== LEAK SUMMARY:
==8835== definitely lost: 0 bytes in 0 blocks
==8835== indirectly lost: 0 bytes in 0 blocks
==8835== possibly lost: 0 bytes in 0 blocks
==8835== still reachable: 552 bytes in 8 blocks
==8835== suppressed: 0 bytes in 0 blocks
==8835==
==8835== For lists of detected and suppressed errors, rerun with: -s
==8835== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
In the file indicated by Valgrind as the one causing the memory leak, the only potential cause is the presence of the 8 regex. The file contains only those regex, along with two function prototypes that, in their body, perform a match with these regex against an input string.
I compile the regex into a .ads file (sf_lexer.ads), and here is a code snippet:
package RE renames GNAT.Regpat;
Number: RE.Pattern_Matcher := RE.Compile("[1-9][0-9]*");
Character: RE.Pattern_Matcher := RE.Compile("'.'");
String_t: RE.Pattern_Matcher := RE.Compile("""([^""]*)""");
Equal: RE.Pattern_Matcher := RE.Compile("=");
Semicolon: RE.Pattern_Matcher := RE.Compile(";");
Types: RE.Pattern_Matcher := RE.Compile("^(void|int|char|str)$");
Variable: RE.Pattern_Matcher := RE.Compile("^[a-zA-Z_][a-zA-Z0-9_]*$");
Keyword: RE.Pattern_Matcher := RE.Compile("^(if|else|loop|return|int|char|str)$");
Is it indeed a memory leak issue with GNAT.Regpat? Should I manually free the memory occupied by the compiled regex patterns?
Thank you all for the support.
Upvotes: 1
Views: 51
Reputation: 6430
This is not a memory leak, as such. It's just memory that has been allocated, and is "still reachable" (as in, not deallocated) on exit. A leak would be allocated memory that are no longer reachable, such as an access value being reallocated without first being deallocated.
Most modern OSes automatically reclaim all allocated memory on exit, so a little bit of "still reachable" should be fine.
If valgrind complains about "definitely lost", "indirectly lost" or "possibly lost", then you might have a problem.
Upvotes: 1