I am learning C and today I wrote some code to turn roman numerals to numbers.
In my program I have a const int MAXWORTLEN = 16;
inside of int main()
, as well as an array of booleans, which I have declared with:
bool *vorzeichen = calloc(MAXWORTLEN, sizeof(bool));
, which I free()
in the end.
I am programming in CLion which sometimes gives little tips to "improve" the program like making an int
into a const int
if it fits the case. It also warns against memory leaks, unreachable code, etc.
By keeping my MAXWORTLEN
a const int
, CLion warns that "Allocated memory is leaked"
. By changing to constexpr int MAXWORTLEN = 16;
, as it suggests, the warning goes away.
All warnings that Clion gives are:
Function 'main' always returns 0 :22
Allocated memory is leaked :29
Leak of memory allocated in function 'main' :33
Variable 'MAXWORTLEN' can be made constexpr :23
The file is a .c file. I am using build tool ninja and gcc as a C compiler.
#include <stdio.h>
#include <stdlib.h>
int rom_wert(char c) {
if(c>='a' && c<='z') {
c = c + ('A' - 'a');
}
switch (c) {
case 'I': return 1;
case 'V': return 5;
case 'X': return 10;
case 'L': return 50;
case 'C': return 100;
case 'D': return 500;
case 'M': return 1000;
default: return -1;
}
}
int main() {
constexpr int MAXWORTLEN = 16;
printf("Eingabe: ");
char *eingabe = calloc(MAXWORTLEN, sizeof(char));
scanf("%15s", eingabe);
bool *vorzeichen = calloc(MAXWORTLEN, sizeof(bool));
for(int i=0; eingabe[i] != '\0'; i++) {
if(rom_wert(eingabe[i]) == -1) {
return 0;
}
if(rom_wert(eingabe[i]) < rom_wert(eingabe[i+1])) {
vorzeichen[i] = true;
}
}
int summe = 0;
for(int j=0; eingabe[j] != '\0'; j++) {
if(vorzeichen[j] == 1)
summe = summe - rom_wert(eingabe[j]);
else if(vorzeichen[j] == 0)
summe = summe + rom_wert(eingabe[j]);
}
printf("Ausgabe: %d", summe);
free(eingabe);
free(vorzeichen);
return 0;
}
Where is the memory leak in the original code, and how does constexpr
resolve it?
Any answer is greatly appreciated, as my only goal in this exercise is to learn :)
Where is the memory leak in the original code
The memory leak occurs when the return 0
line is executed in the for-loop near the top of main. The return 0
means that the rest of the function is never executed and therefore the calls to free()
are never made. (On a modern OS with resource-tracking, that doesn't much matter since the program then exits and all of its memory is automatically freed anyway, but it is still technically a leak)
and how does constexpr resolve it?
I don't think it does, but my suspicion is that tagging the variable with constexpr
may have allowed the compiler/optimizer to implicitly remove the calloc()
and free()
calls entirely and replace them with one or more stack-based arrays instead, in which case there would be no memory leak as there was never any heap allocation to begin with.