打印
[其他]

内存泄漏以及原因

[复制链接]
2411|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、什么是内存泄漏?
在C语言中,我们可以使用malloc、calloc、realloc等函数来动态地申请内存空间,这些内存空间是从堆(heap)中分配的,与程序的生命周期无关,只有当我们显式地调用free函数来释放这些内存空间时,它们才会被回收。这样,我们就可以根据需要动态地调整内存的大小和数量,提高内存的利用率和程序的灵活性。

但是,这种动态内存分配的方式也带来了一些风险,就是如果我们在使用完动态分配的内存空间后,忘记或者无法释放它们,那么这些内存空间就会一直占用着系统的内存资源,无法被其他程序使用,这就是内存泄漏(memory leak)。

简单的内存泄漏示例代码:

 1#include <stdlib.h>  
2
3void allocateMemory() {  
4    int* ptr = (int*)malloc(sizeof(int));  
5    if (ptr == NULL) {  
6        exit(1);  
7    }  
8    *ptr = 10;  
9    // 注意:这里缺少了free(ptr)的调用,导致内存泄漏  
10}  
11
12int main() {  
13    for (int i = 0; i < 10000; i++) {  
14        allocateMemory();  
15    }  
16    return 0;  
17}

上面的例子中,allocateMemory 函数使用 malloc 分配了一块内存,但之后并没有调用 free 释放这块内存。因此,每次调用 allocateMemory 函数时,都会有一块内存无法被释放,这就是内存泄漏。

二、内存泄漏的常见原因
1.内存泄漏的常见原因
(1)忘记释放内存

当使用malloc、calloc或realloc等函数分配内存后,必须在使用完内存后使用free来释放它。如果忘记释放,就会导致内存泄漏。

示例代码:

1#include <stdlib.h>  
2
3void forgetToFree() {  
4    int* ptr = (int*)malloc(sizeof(int));  
5    if (ptr != NULL) {  
6        *ptr = 10;  
7        // 忘记调用 free(ptr)  
8    }  
9}  
10
11int main(int argc, char *argv[]) {  
12    for (int i = 0; i < 10000; i++) {  
13        forgetToFree();  
14    }  
15    return 0;  
16}

(2)重复释放

尝试多次释放同一块内存是非法的,可能导致程序崩溃。

示例代码:

 1#include <stdlib.h>  
2
3void doubleFree() {  
4    int* ptr = (int*)malloc(sizeof(int));  
5    if (ptr != NULL) {  
6        free(ptr);  
7        // 重复释放同一块内存  
8        free(ptr);
9    }  
10}  
11
12int main(int argc, char *argv[]) {  
13    doubleFree();  
14    return 0;  
15}

(3)内存泄漏在函数中

在函数内部分配的内存,如果没有被返回给调用者,调用者就无法释放它。

示例代码:

 1#include <stdlib.h>  
2
3void allocateInFunction() {  
4    int* ptr = (int*)malloc(sizeof(int));  
5    if (ptr != NULL) {  
6        // ptr 没有返回给调用者,导致内存泄漏  
7        *ptr = 10;  
8    }  
9}  
10
11int main(int argc, char *argv[]) {   
12    allocateInFunction();  
13    // 无法释放 allocateInFunction 中分配的内存  
14    return 0;  
15}

(4)指针丢失

如果丢失了指向已分配内存的指针,那么这块内存就无法被释放。

示例代码:

 1#include <stdlib.h>  
2int* someOtherFunction() {  
3    // 假设这个函数返回一个新的指针  
4    int* newPtr = (int*)malloc(sizeof(int));  
5    return newPtr;  
6}  
7
8void loseReference() {  
9    int* ptr = (int*)malloc(sizeof(int));  
10    if (ptr != NULL) {  
11        *ptr = 10;  
12        // 假设ptr被用于某个全局数据结构或传递给其他函数  
13        // ...  
14        // 然后ptr的引用丢失了,例如它指向的内存被另一个指针覆盖  
15        // 假设这个函数返回一个新的指针  
16        int* newPtr = someOtherFunction();
17        // 现在ptr指向了新的内存,原先的内存泄漏了  
18        ptr = newPtr;
19        // 或者ptr可能被置为NULL,或者超出了其作用域  
20    }  
21}  
22
23int main(int argc, char *argv[]) {  
24    // 调用函数,ptr曾经指向一块内存  
25    loseReference();  
26    // 但由于在某处丢失了ptr的引用,这块内存无法被释放,导致内存泄漏  
27    return 0;  
28}

使用特权

评论回复

相关帖子

沙发
moore21| | 2024-6-21 13:13 | 只看该作者
用cppcheck 工具很容易查到C代码里的内存泄漏。

使用特权

评论回复
板凳
OKAKAKO| | 2024-6-22 19:51 | 只看该作者
尝试多次释放同一块内存是非法的,可能导致程序崩溃。

使用特权

评论回复
地板
中国龙芯CDX| | 2024-6-26 14:09 | 只看该作者
这种动态内存分配的方式也带来了一些风险,就是如果我们在使用完动态分配的内存空间后,忘记或者无法释放它们,那么这些内存空间就会一直占用着系统的内存资源,无法被其他程序使用,这就是内存泄漏(memory leak)。

使用特权

评论回复
5
forgot| | 2024-6-27 08:39 | 只看该作者
很多复杂的程序动态分配内存到后面很多都不能保证一定得到释放。

使用特权

评论回复
6
LOVEEVER| | 2024-7-15 14:46 | 只看该作者
尝试多次释放同一块内存是非法的导致程序崩溃

使用特权

评论回复
7
szt1993| | 2024-7-17 19:24 | 只看该作者
内存空间就会一直占用着系统的内存资源,无法被其他程序使用,这就是内存泄漏

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

199

主题

1668

帖子

2

粉丝