内存管理,是指软件运行时对计算机内存资源的分配和使用的技术。其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源。内存管理是C语言编程中重要的组成部分,C语言中的内存需要手动分配,手动释放,一般遵循分配多少,释放多少,以免造成内存泄漏。内存管理是一项重要且复杂的事情,理解内存管理,对后面课程及项目的学习会有很大的作用。
之前创建变量,是系统自动分配的内存,放在栈内存中,销毁后被系统自动回收,手动分配的内存,放在堆内存中,需要手动释放。千万不要忘记销毁对象手动将内存释放并将指针置空(NULL)。
内存分配常用头文件:malloc.h
malloc函数:
# include <stdio.h> # include <malloc.h> int main(void) { int i = 3; //静态分配内存,给变量i分配了4个字节空间。 int * p = (int *)malloc(20); /* 1. 动态分配内存,要使用malloc函数,必须添加malloc.h头文件。malloc是 memory(内存) allocate(分配)的缩写。 2. malloc函数只有一个形参,并且形参是整型。 3. 20表示请求系统为本程序分配20个字节内存空间。 4. malloc函数的返回值为第一个字节的内存地址,赋值给指针变量p。 malloc函数的返回值为void * 类型,void * 类型也叫干地址,即无实际意义的地址。 并且需要强制类型转换(int *),将所分配的内存转换为指针变量p所定义的int * 类型。 共分配了20个字节,每个int类型变量占4个字节,所以共生成了5个变量(动态数组)。 第一个变量为*p,第二个为*(p+1),依次类推,第i个为*(p+i)。 5. 注意:指针变量p所占的内存是4个字节,为静态分配的,p所指向的内存为动态分配的。 */ *p = 3; //为第一个变量赋值3 *(p+1) = 5; //为第二个变量赋值5 printf("%d, %d\n", *p, *(p+1)); free(p); //free()函数,将p指向的内存空间释放掉。注意:p本身的内存空间是静态的,不会被释放,只能在程序结束后被系统释放。 return 0; }
静态分配内存:
# include <stdio.h> # include <malloc.h> int main(void) { printf("呵呵!\n"); while (true) { int * p = (int *)malloc(100); //无限循环分配内存 } return 0; }
free函数:
# include <stdio.h> # include <malloc.h> //free()函数也位于malloc.h头文件中,所以要声明。 int main(void) { int i = 3; int * p = &i; free(p); //p所指向的变量i的内存是静态分配的,不能够手动释放,这样写会出错。 printf("%d\n", i); return 0; } //运行直接报错
动态构造一维数组:
# include <stdio.h> # include <malloc.h> int main(void) { int a[5]; //静态构造了5个元素的一维数组。 int * pArr; int len; int i; printf("请输入需要存放的元素的个数:"); scanf("%d", &len); pArr = (int *)malloc(4*len); //动态构造了一维数组,长度为len,数组类型为int类型,数组名即为pArr。类似于 int a[5]; 数组名PArr与a相同。 //动态数组的操作与静态数组相同,数组名pArr存放了数组第一个元素的地址。 for (i=0; i<len; ++i) { printf("请输入第%d个元素的值:", i); scanf("%d", &pArr[i]); //与静态数组操作相同。 } printf("一维数组中的内容为:\n"); for (i=0; i<len; ++i) printf("a[%d] = %d\n", i, pArr[i]); realloc(pArr,100); //realloc()重新分配内存函数,用于改变数组的长度,后跟两个参数,第一个是数组名,第二个是重新分配的数组字节数, //如此函数即将pArr数组所占内存改为100字节。 //当内存改变时,增长:如50字节变为100字节,前50字节内容保留不变,再增加50字节内存。 // 缩小:如150字节变为100字节,前100字节内容保留,后50字节内容丢失。 free(pArr); //free()函数释放指针变量所指向的变量内存,当释放数组名时,将全部释放整个数组所占的内存,而不是只释放数组名所指向的第一个元素变量内存。 printf("一维数组中的内容为:\n"); for (i=0; i<len; ++i) printf("a[%d] = %d\n", i, pArr[i]); return 0; }
动态内存跨函数使用:
将指针变量传递过去
# include <stdio.h> void f(int ** q) { int i = 5; *q = &i; return; } int main(void) { int * p; f(&p); printf("%d\n", *p); //这样写逻辑上是错误的,因为函数f()已经运行结束,p所指向的变量i已经释放,不存在了,不能够再读取输出。 //程序没有报错的原因是因为此软件(VC++6.0)比较弱智。 return 0; }
动态内存跨函数使用2:
/* 2013年1月27日21:05:44 动态内存的跨函数使用 (在使用时都需要传址) 在main()函数中构造 在change()函数中赋值 在printf()函数中输出 */ # include <stdio.h> # include <malloc.h> void change(int * q) { *q = 10; return; } void printf(int * r) { printf("%d\n", *r); return; } int main(void) { int * p = (int *)malloc(sizeof(int)); //构造动态内存变量。 *p = 3; change(p); printf(p); return 0; }
练习示例:
# include <stdio.h> # include <malloc.h> int main(void) { double i = 66.6; double * p = &i; printf("%d\n", sizeof(*p)); p = (double *)malloc(sizeof(double)); *p = 88.8; free(p); free(p); //指针变量p所指向的内存空间不能被重复释放,即野指针不能再被释放,会导致出错。 return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-22 19:01:10