- 函数指针
//定义一个函数 void message(){ } //通过指针调用函数 void (*p) () =message; p();
函数指针不仅仅只是一个地址,必须明确的指定函数的指针类型,以及返回值和参数列表//带返回值和参数列表的函数指针 double add(double a, double b){ return a+b; } //通过指针调用函数 double (*p1) (double a, double b) =add; p1(2,3)
- 动态分配内存
- c语言中内存分配(逻辑分区)
-
栈区:自动分配自动释放(存放的内容:主要存放的是函数的参数值和局部变量),更高效。
栈先进后出,队列后进后出//40MB int四字节 //报错:Stackoverflow栈内存溢出, //栈区内存的大小:操作系统和C库的版本相关(大小是有限制的) //数组的数据默认保存在栈内存中 int a[1024 * 1024 * 10];
-
堆区(malloc()开辟一块新的内存空间):需要自己回收释放内存
void heapMethod(){ //在堆区开辟一个10M的内存空间 int *p =(int*)malloc(1024*1024*10); }
-
全局区和静态区:全局变量和静态变量(也是系统自动管理,当我们的应用程序结束的时候释放)
-
程序代码区:存放程序代码
-
字符常量区:存放常量字符串,应用程序结束系统自动释放
-
- malloc
动态分配内存,返回void,在c++中void方法指针可以指向任何类型的方法指针,类似java 中的Object类型 - 动态指定数组的大小
//开辟一块内存,可以存储五个数字 int* p =(int *)malloc(5* sizeof(int)); int i=0; for(;i<5;i++){ p[i] =100; }
- 重新分配内存(realloc重新分配内存/calloc分配内存)
realloc更改已经配置的内存空间- 缩小:会导致一部分数据的丢失
- 扩大:(连续不断线性排序)
- 情况1:如果当前内存区域还没有使用完成,就会直接追加(原来开辟五条内存,使用两条,增加三条,会填补之前空闲的内存)(注意:返回原指针)
- 情况2:如果当前内存空闲的空间不够,那么就会从新在堆内存中寻找能够容纳该数据大小的内存区域,将原来的数据拷贝,然后在添加新的数据(原来开辟五条内存,使用两条,增加六条,重新开辟内存)(注意:返回值为新的内存地址,原来的指针被释放)
- 情况3: 如果所有内存已经分配完,申请内存失败,将返回NULL,而且原来的指针有效。
//开辟一块内存区域,可以存储五个数字 //第一个参数:数组长度 //第二个参数:每个元素大小 int* p =(int*)calloc(5,sizeof(int)); int i=0 for(;i<5;i++){ p[i] =10; } //改变原始内存区域的大小,增加或者是减小 //重新输出数组的数据 int* p1 =(int*) realloc(p,(5+6)*sizeof(int)); i=0 for(;i<6;i++){ p1[i] =10; }
- 回收内存-堆区(free)
void heapMethod(){ //在堆区开辟一个10M的内存空间 int *p =(int*)malloc(1024*1024*10); //回收内存 free(p); }
- 内存分配注意事项
- 不能多次释放内存
- c语言中内存分配(逻辑分区)
网友评论