本文主要是介绍C语言学习(八)typedef 虚拟内存 malloc/free,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 一、typedef 类型重定义
- (一)使用
- (二)define和typedef的区别
- 1. 编译处理的阶段不同
- 2. 功能不同
- 二、虚拟内存
- (一)虚拟内存分布
- (二)内存分布
- 1. 静态分配
- 2. 动态分配
- 三、malloc/free函数
- (一) malloc函数
- (1)定义
- (2)使用
- (二) free函数
- (三) 使用
- 四、内存泄漏
- (一)概念
- (二) 规避方法
- (三)示例
一、typedef 类型重定义
(一)使用
typedef <数据类型> <标识符>
typedef int int32_t; typedef int arr_t[2][3];//两行三列的二维数组类型typedef int(*fun_t)(int,int); //定义int(*)(int,int)类型
(二)define和typedef的区别
1. 编译处理的阶段不同
define在预处理阶段,typedef参与编译阶段
- 注:编译的过程:
- 预处理:展开头文件,删除注释,宏替换
gcc - E hello.c -o hello.i
hello.i 就是预处理文件。预处理不会检查语法错误。 - 编译:语法统计,词法统计,语义分析
gcc -S hello.i -o hello.s
生成一个汇编文件。编译会检查语法错误 - 汇编:
gcc -c hello.s -o hello.o
生成一个二进制文件。 - 链接:链接库文件,生成一个可执行的二进制文件
gcc hello.o -o hello
2. 功能不同
define是字符串原样替换;typedef是用于类型重定义
二、虚拟内存
(一)虚拟内存分布
- 内核空间:(0xcccc cccc~0xffff ffff)程序共用,不允许用户使用
- 栈区:空间自动申请,自动释放;向下生长
主要存放局部变量,未初始化时是乱值。
(栈区空间,windows是2M,可以调至10M;在Linux中是8M) - 堆区:手动申请,手动释放;向上生长
malloc / realloc / calloc
(堆区空间,大概1.9G) - 常量区:
.bss
段:未初始化的全局变量
.data
段 :初始化的全局变量
.readonly
段:只读段
.text
段 (代码区):程序代码
mmu固件:将虚拟内存映射到物理内存中。
eg:分析以下数据存放在内存中的位置:number1 , number2, number3, number4, p1, p2 ,p3 *p1,*p3, function, *p2
include <stdio.h>int number1;
未初始化的全局变量:常量区-->.bss段
int number2 = 10;
初始化的全局变量:常量区-->.data段
字面量值10存储在常量区。int function() 代码:常量区-->代码区
{int number3 = 30; 初始化的局部变量:栈区int number4; 未初始化的局部变量:栈区
}
int main() 代码:常量区-->代码区
{char * p1 = "hello world"; p1 局部变量:栈区*p1:常量区-->readonly段char p2[]= "abc" p2 局部变量:栈区*p2:栈区char *p3 = (char *)malloc(20); p3 局部变量:栈区; p3指向的内存空间 堆区free(p3);p3 = NULL;
}
- 注:当程序加载到内存中时,number2的内存空间(在.data段)会被分配,
并且其值会被初始化为10(这个值来源于常量区,但在运行时它是存储在.data段中的)。
(二)内存分布
C语言分配内存的方法:静态分配 动态分配
1. 静态分配
在编译节点的时候,已经确定了分配空间大小。
eg:int a=10;
intarr[2][2];
2. 动态分配
编写程序时,不确定要申请多少空间,在执行时根据需要进行的空间分配。
eg:malloc分配的空间就属于动态分配。
三、malloc/free函数
(一) malloc函数
(1)定义
头文件(标准库文件):
#include <stdlib.h>函数原型:
void *malloc(size_t size);函数功能:在内存中(堆)区中开辟指定大小的地址连续的空间。函数参数:size_t 无符号整型,size表示开辟多少字节空间。函数返回值:成功,返回开辟空间的首地址;失败,返回一个NULL。
(2)使用
申请空间为一段连续的空间:
① 可以使用下标进行访问
②可以通过指针进行访问
(二) free函数
头文件(标准库文件):
#include <stdlib.h>函数原型:
void free(void *ptr);函数功能:释放手动申请的空间。函数参数:void* ptr: malloc/realloc/calloc申请的空间的首地址
- 注:释放已经释放过的指针会造成程序错误。
- 但是指针指向NULL时,释放多次都不会报错。
(三) 使用
#include <stdio.h>
#include <stdlib.h>int main()
{//申请空间int *p =mymalloc(20);if(!p){printf("create fail!\n");return -1;}//向空间内写值*p = 10;*(++p)= 20;//读值for (int i=0;i<20;i++){printf("%d ",*(p+i));}//释放空间free(p);p = NULL;/*释放完空间后,将指针指向NULL/指向NULL后,再次释放不会报错*/
}int mymalloc(int size)
{int *p = (int *)malloc(size);if(!p){printf("fail!\n");return -1;}else{prnintf("sucess:%p\n",p);}return 0;
}
eg :
功能需求 :
定义一个函数: create 功能: 在内存中申请n个字节大小. n是一个参数.
这个函数的返回值是指针类型.
set(指针)函数 功能: 从键盘中输入n个值, 将N个值存入 create创建的空间中.
sort函数():使用冒泡排序对这n个值进行排序.
max函数(): 返回空间中的最大值
min函数(): 返回空间中的最小值.、
代码实现 :
#include <stdio.h>
#include <stdlib.h>int min(int *arr,int len);
int max(int *arr,int len);
void sort(int *arr,int len);
void set(int *a,int n);
int* create(int size);
void show(int *arr,int size);
void create_noReturn(int **p,int size);//使用二级指针传参int main()
{int size;//申请空间printf("please input size:");scanf("%d",&size);/*** * int *p = NULL;* create_noReturn(&p,size);***/int *p = create(size);//20个字节,5个int//判断p空间是否申请成功if(p!){printf("create fail!!");return -1;}//向空间内写值set(p,size);//排序,读值sort(p,size);show(p,size);printf("MAX:%d\n",max(p,size));printf("MIN:%d\n",min(p,size));//释放空间free(p);p = NULL;
}
void show(int *p,int size)
{for(int i=0;i<5;i++){printf("%d ",*(p+i));}putchar(10);
}
//申请n字节大小,返回值是申请空间的指针
int* create(int size)
{int *p = (int *)malloc(4*size);if(!p){printf("fail!\n");return NULL;}return p;
}
//无返回值的空间分配
void create_noReturn(int **p,int size)
{int s=4*size;*p =(int*)malloc(s);} void set(int *a,int n)
{for(int i=0;i<n;i++){printf("please input %d num:",i+1);scanf("%d",a+i); }
}//排序
void sort(int *arr,int len)
{int flag = 0;for(int i=0;i<len-1;i++){flag = 0;for(int j=0;j<len-i-1;j++){if(*(arr+j)>*(arr+j+1)){int temp=*(arr+j);*(arr+j)=*(arr+j+1);*(arr+j+1)=temp;flag=1;}}if(!flag) break;}
}//最大值
int max(int *arr,int len)
{int max = *arr;for(int i=0;i<len;i++){if(max<(*(arr+i)))max = *(arr+i);}return max;
}//最小值
int min(int *arr,int len)
{int min = *arr;for(int i=0;i<len;i++){if(min>(*(arr+i)))min = *(arr+i);}return min;
}
四、内存泄漏
(一)概念
在C语言中调用malloc/calloc/realloc函数时,申请内存后没有调用free函数进行释放内存,导致内存越用越少。
(二) 规避方法
当空间使用完毕后,及时释放内存。
(三)示例
int main()
{int * p =malloc(20);p = malloc(20);free(p);return 0;
}
此时p指向第二次申请的内存空间,没有指针指向第一次申请的内存空间。
这篇关于C语言学习(八)typedef 虚拟内存 malloc/free的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!