虽然我很少使用C语言,但我一直在思考我总是被告知的规则,“如果你调用malloc()
(或new
),你必须调用free()
(或delete
)”。这让我想知道GCC(或其他C编译器)是否试图执行任何类型的内存并警告用户潜在的问题。我从来没有听说过,所以我怀疑不是这样的,但我想知道。
下面是我使用的示例:
#include <stdlib.h>
int main() {
int* first = malloc(sizeof(int) * 10);
int* second = malloc(sizeof(int) * 10);
int i = 0;
for (; i < 10; i++) {
first[i] = i * 2;
second[i] = i * 10;
}
free(first); /* Forgot to free second */
return 0;
}
使用gcc -Wall free_test.c
编译时,未生成任何警告。虽然我可以理解为什么编译器不能提供一个完美的答案,因为你正在处理堆内存,并在运行时管理它,为什么编译器似乎没有试图提供一个警告,可能有一个内存泄漏?
我的一些想法,为什么包括:
1.编译器可能没有一个完美的方法来告诉内存何时被释放。例如,如果其中一个指针被传递到函数中并从函数中释放,编译器可能无法分辨。
1.如果一个不同的线程获得了内存的所有权,编译器将无法判断是否有其他线程正在释放内存。
3条答案
按热度按时间x6yk4ghg1#
通过静态分析(更不用说通过琐碎的静态分析)无法检测到的案例远远多于那些能够检测到的案例。编译器的作者大概认为,给GCC增加这种额外复杂性的好处远远超过了成本。
zpgglvta2#
这比计算
free
和malloc
调用要复杂一些。假设有一个库,其中一些库函数假定库调用malloc
,但假定库的用户将调用free
。wb1gzix03#
GCC有一个特殊的
-fanalyze
模式which does a number of different checks,包括用于malloc
泄漏。出于演示的目的,我不得不修改您的代码,将其转移到一个单独的
foo()
函数中,因为当它在main()
中时,malloc的抱怨就消失了。我假设GCC假定从main返回无论如何都会释放内存。我还必须添加一个-Wno-analyzer-possible-null-dereference
,以消除关于malloc()
的结果可能是NULL
* 的警告(以避免不必要地修改问题的代码)*。代码:
结果: