C语言管理内存泄露的问题:
内存泄露:指一块动态分配的内存, 我们不再拥有指向这块内存的指针, 因此我们没有办法将它返还给程序供以后重新使用.
引起内存泄露的可能性?
1)重新赋值
Int *p=(int*)malloc(40);
Int *q=(int*)malloc(40);
p=q; p原来指向的空间,再也无法返回给系统。。所以造成泄露。
Int *temp;
Int *p=(int*)malloc(40);
temp=p;//吧p的地址存放到临时变量temp中。
Int *q=(int*)malloc(40);p=q;如果再想使用p原来申请的内存空间,所以我们可以 p=temp;
1)先释放父级
P-à|q| | |内存区域
|
|
| | | |内存区域
假设上述两个区域都是动态申请和分配,需要手工释放。
如果free(p)
将会造成内存泄露?
原因是:p所指向的内存中有区域新申请新的子内存空间。
如果p被释放,那么p内存区域中指向的子内存空间无法释放。
解决方案:
先释放子内存空间 free(q);
在释放父级空间 free(p);
2)返回值(新申请的动态内存地址)的不正确处理
Int *apply(){
Return (int*)malloc(20);//返回的是新申请的内存空间的首地址
}
Apply();//进行调用 apply()函数的返回值,没有给任何指针。
、、、、、、、、、、、、、、
野指针?
指向“垃圾”内存的指针?
1)未被初始化的指针 解决:=0;或者=NULL;
2)free之后没有被赋值NULL; 解决:=0;或者=NULL;
3)指针访问越界 解决:不让越界;
、、、、、、、、、、、、、、、、、、、、、、、、、、
C语言中文件操作
程序中文件的概念
存储在外部介质上的数据集合
简单分类:
程序的源文件 .c .obj .exe
程序数据文件 从外部或取得一批数据
C语言对文件操作有以下步骤:
1. 导入库函数 stdio.h
2. 定义文件的指针 FILF(特殊的结构体,不许进行声明)
3. 打开文件 fopen(【路径】文件名,打开方式)
路径------./ ../ D:\\temp\a.txt
打开方式:
r 只读
w 只写
a 追加
r+ 读写
w + 读写
a+ 读取
t 打开文本文件
b 打开一个二进制文件
4. 文件读写操作
5. 关闭文件指针
读写字符的函数
fgetc(fpr) 从文件中读取字符
fputc(ch,fpw) 把ch写入到fpw 指向的文件中
fgets()
fputs()
fread()
结构体?
一种新的数据结构,可以不同的数据类里数据集合,内存存放是连续的。
1)定义数据结构
Struct 结构体名{
成员类表;}结构变量1,结构变量2;
结构体变量可以省略,但是必须有“;”。
2)定义并且初始化
1.struct 结构体名{
成员类表;}结构体变量名={值1,值2,………}
2.struct 结构体名 结构体变量名={值1,值2,……}
结构体成员变量的访问
1. 结构体变量名
结构体变量名,成员变量名
2. 使用结构体的指针进行访问
定义一个指向结构体的指针?
Struct 结构体名 *指针名
结构体指针指向结构体变量
Structstudent stu;//定义结构体变量
P=&stu;//让指针p纸箱结构体变量
文件操作
文件:
1) 程序文件:包括源程序文件(后缀为.c)、目标文件(后缀为.obj)、可执行文件(后缀为.exe)等。这种文件的内容是程序代码。
2)数据文件:文件的内容不是程序,而是供程序运行时读写的数据,如在程序运行过程中输出到磁盘(或其他外部设备)的数据,或在程序运行过程中供读入的数据。如一批学生的成绩数据,或货物交易的数据等。
文件标识包括三部分:
1)文件路径
2)文件名主干
3)文件后缀
文件路径表示文件在外部存储设备中的位置。
文件缓冲区
所谓缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区
文件操作的基本步骤:引入头文件(stdio.h ) ,定义文件指针
打开文件,文件读写,关闭文件
fopen函数调用形式
fopen(文件名,使用文件方式);
联合体
使几个不同的变量共享同一段内存的结构,称为 “共用体”类型的结构。
定义一个共用体的一般形式:
union联合名 {
数据类型 成员名1;
};
内存管理
静态分配:编译器在处理程序源代码时分配
动态分配: 程序执行时按动态要求来分配
动态分配和静态分配的区别:
静态内存分配是在程序执行之前进行的, 因而效率比较高,但是它缺少灵活性,要求在程序执行之前就知道所需内存的类型和数量
静态对象是有名字的变量,我们直接对其进行操作. 而动态对象是没有名字的变量,我们通过指针间接地对它进行操作.
静态对象的分配与释放由编译器自动处理.动态对象的分配与释放, 必须由程序员显式地管理, 相对来说比较容易出错
Malloc
int *p = (int *)malloc (sizeof(int));
calloc函数
void *calloc(unsigned n,unsigned size);
free函数
void free(void *p);
realloc函数
void *realloc(void *p,unsigned int size);