我正在学习 C,今天我写了一些代码将罗马数字转换为数字。
在我的程序中,我在
const int MAXWORTLEN = 16;
内部有一个 int main()
,以及一个布尔值数组,我已经声明了:
bool *vorzeichen = calloc(MAXWORTLEN, sizeof(bool));
,最后我free()
。
我正在 CLion 中编程,有时会提供一些小提示来“改进”程序,例如将
int
变成 const int
(如果适合的话)。它还会警告内存泄漏、无法访问的代码等。
通过将我的
MAXWORTLEN
保留为 const int
,CLion 警告说 "Allocated memory is leaked"
。如其所示,通过更改为 constexpr int MAXWORTLEN = 16;
,警告就会消失。
Clion 给出的所有警告是:
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
该文件是.c 文件。我使用构建工具 ninja 和 gcc 作为 C 编译器。
#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;
}
原代码中内存泄漏在哪里,
constexpr
是如何解决的?
非常感谢任何答案,因为我在这个练习中的唯一目标是学习:)
原代码内存泄漏在哪里
内存泄漏发生在 main 顶部附近的 for 循环中执行
return 0
行时。 return 0
意味着该函数的其余部分永远不会执行,因此永远不会调用 free()
。 (在具有资源跟踪的现代操作系统上,这并不重要,因为程序随后退出并且所有内存都会自动释放,但从技术上讲它仍然是泄漏)
constexpr 如何解决它?
我不认为如此,但我怀疑用
constexpr
标记变量可能允许编译器/优化器隐式删除 calloc()
和 free()
调用并用基于堆栈的 char 替换它们相反,在这种情况下,不会出现内存泄漏,因为一开始就没有任何堆分配。
原代码内存泄漏在哪里
如果这段代码片段中的
return
...
if(rom_wert(eingabe[i]) == -1) { return 0; }
... 被执行,然后控制离开
main()
,而没有释放任何已分配的块。 这大概就是 CLion 所抱怨的,尽管在大多数操作环境中,这种特殊的“泄漏”是良性的:操作系统通常会在程序终止时清理仍然分配的任何内存。
,
如何解决?constexpr
将变量声明为
constexpr
并不能解决这个问题。 我无法解释为什么 CLion 会影响 CLion 是否呈现诊断。 此外,我不能说我很关心 CLion 将 MAXWORTLEN
声明为 constexpr
的建议。 这样做不会产生我认为有什么特别的优势,并且会降低程序与旧版 C 编译器的兼容性,因为 constexpr
直到几周前才发布的 C23 才被引入标准 C..