四、用free函数释放非动态内存函数开辟的空间
我们都知道,动态内存函数在堆区,
局部变量在栈区,全局变量在静态区
#include<stdio.h> #include<stdlib.h> int main() { int arr[10] = { 0 }; int *p = arr;//p指向arr首元素地址 for (int i = 0; i < 10; i++) { int kc=*(p + i) = i; printf("%d ", kc); } free(p);//用了free释放在栈空间上的错误,会导致程序崩溃 p = NULL; system("pause"); return 0; }
用了free函数堆区释放在栈空间上的内存,导致程序崩溃
1.程序崩溃如图所示:
所以我们在使用free函数时要先判断是不是动态内存函数申请的空间(malloc calloc realloc)。
五、多次用free释放同一空间
使用了free多次释放同一指针指向申请的内存空间。
#include<stdio.h> #include<malloc.h> int main() { int*p=(int*)malloc(5*sizeof(int)); if(p!=NULL) { for(int i=0;i<5;i++) { *(p+i)=i; printf("%d ",*(p+i)); } } else { return 0; } free(p);//两次释放导致程序出错 free(p); p=NULL; return 0; }
这种情况容易出现在有许多代码(且前面忘了使指针为NULL),前面释放过后,p还是指向原位置。再次释放时为非法了,所以进行free函数释放时,记得free(p)后,要将p=NULL;这样就不会出错了,即使在进行n次释放也无所谓了,因为当释放的值是NULL时,free函数什么也不做。
如下改正:
#include<stdio.h> #include<malloc.h> int main() { int*p=(int*)malloc(5*sizeof(int)); if(p!=NULL) { for(int i=0;i<5;i++) { *(p+i)=i; printf("%d ",*(p+i)); } } else { return 0; } free(p);//free(p);和p=NULL配套使用就没问题 p=NULL; return 0; }
六、动态内存函数申请空间后未进行释放(导致内存泄漏)
写一个极端点的例子效果更明显
#include<stdio.h> #include<stdlib.h> int main() { while(1) { int *=(int*)malloc(4);死循环申请4个字节来模拟多次使用动态内存函数不释放 } return 0; }
这个采用放大的思想将多次使用动态内存函数申请内存空间而不释放的场景
这个代码运行之后我们可以看到内存并不断减少。具体操作看下图
细致观看内存泄漏的方法:
1.屏幕下方右击鼠标找到任务管理器:
2.找到性能
3.代码运行后观看内存的变化(涨到一定内存后由于系统的保护将不再涨了)
这就是全部动态内存的问题。