0


【C语言】动态内存管理的常见错误以及解决方法

动态内存管理常见错误

1.对NULL指针的解引用操作

问题:当我们用malloc开辟动态内存失败时,指针将会是空指针。
一般申请的内存过大将会导致开辟动态内存失败。
看下面这个例子

voidtest(){int* p =(int*)malloc(INT_MAX);//申请最大字节,申请的内存过大。*p =20;free(p);}

调用这个函数,并监视p
在这里插入图片描述
可以看到,p的值是0,也就是空指针。
解决
所以,我们在申请动态内存空间后,要判断它是否不为空指针,才进行一系列的操作。避免程序出现问题。

voidtest(){int* p =(int*)malloc(INT_MAX);if(NULL== p){perror("malloc");return;//如果为空指针,直接return结束}else{*p =20;}free(p);
    p =NULL;}

2.对动态开辟空间的越界访问

问题:
同数组一样,动态开辟的内存空间也可能被越界访问。

voidtest2(){int* p =(int*)malloc(5*sizeof(int));//开辟了20个字节,只能存5个int类型的数据if(NULL== p){perror("malloc");return;}else{for(int i =0; i <10; i++)//这里却要存10个int类型的数据{*(p + i)= i;}}free(p);
    p =NULL;}

调用这个函数
在这里插入图片描述
程序直接崩溃。
解决:

voidtest2(){int* p =(int*)malloc(5*sizeof(int));if(NULL== p){perror("malloc");return;}else{for(int i =0; i <5; i++){*(p + i)= i;}}free(p);
    p =NULL;}

1.尽量不要越界访问
2.可以在存满的情况下加个realloc

3.对非动态内存开辟使用free释放

问题:很多人刚学malloc的时候,知道malloc后一定要free释放,避免内存泄漏。
但是却常常走火入魔,写完一段程序就free,即使代码里面没有开辟动态内存。
比如:

intmain(){int a =10;int* p =&a;free(p);
    p =NULL;return0;}

在这里插入图片描述

运行程序,直接崩溃
解决: free()是释放动态开辟的内存空间,不是什么都能释放的。

4.使用free释放动态开辟内存的一部分

free()释放动态开辟的内存空间的时候,括号里面放的是一定开辟空间的起始地址。
问题:
看下面这一段代码有什么问题?

intmain(){int* p =(int*)malloc(20);if(NULL== p){return1;}for(int i =0; i <5; i++){*p = i;
        p++;//p指向的地址改变了}free(p);
    p =NULL;return0;}

运行程序,程序也会崩溃。因为free(p),p不再指向空间的起始地址。
解决:

intmain(){int* p =(int*)malloc(20);if(NULL== p){return1;}for(int i =0; i <5; i++){*(p + i)= i;//尽量不改变空间的起始地址}free(p);
    p =NULL;return0;}
intmain(){int* p =(int*)malloc(20);if(NULL== p){return1;}int* p2 = p;//如果非要改变p的地址,可以把p的起始地址给p2//free(p2)for(int i =0; i <5; i++){*p = i;
        p++;}free(p2);
    p =NULL;
    p2 =NULL;return0;}

5.对同一块动态内存多次释放

问题:有时候我们写程序的时候,可能会因为粗心多次free了一个动态开辟的内存。 这就体现了free后,把指针置为空的重要性

intmain(){int* p =(int*)malloc(20);if(NULL== p){return1;}for(int i =0; i <5; i++){*(p + i)= i;}free(p);//...   进行了一系列的代码后free(p);//上面free过了}

运行程序,程序崩溃。
解决:

intmain(){int* p =(int*)malloc(20);if(NULL== p){return1;}for(int i =0; i <5; i++){*(p + i)= i;}free(p);
    p =NULL; 把p置为空指针
    
    //...free(p);//free(NULL),free一个空指针,这段代码啥事也没干。}

6.动态开辟内存忘记释放(内存泄漏)

比上面那些问题更严重的问题就是忘记释放,就会造成内存泄漏问题

voidtest(){int* p =(int*)malloc(100);if(NULL!= p){*p =20;}}intmain(){test();while(1);}

大家可以运行这段程序,然后打开任务管理器看一下自己的程序CPU占比,不过不会一直升高,因为有自动保护机制。
解决:
正确的free动态开辟的内存空间。

总结:

对于动态开辟内存malloc,我们既然要向内存使用他的方便之处,就要懂得在使用完后怎么规范地还给内存。
有借有还,再借不难!

标签: c语言

本文转载自: https://blog.csdn.net/iamxiaobai_/article/details/127021356
版权归原作者 有心栽花无心插柳 所有, 如有侵权,请联系我们删除。

“【C语言】动态内存管理的常见错误以及解决方法”的评论:

还没有评论