一:内存分为5大区域
栈区 -- 存放局部变量
堆区 -- 程序运行过程中,动态分配的内存
BSS区 -- 未初始化的全局变量和静态变量
数据段 -- 已经初始化的全局变量和静态变量
代码段 -- 程序编译产生的二进制的数据
内存分配方式:
·1)静态分配,在编译的阶段分配的内存 int a = 10; 静态分配的内存在程序结束后会自动释放
2)动态分配,在程序的运行过程中进行的内存分配 ,动态分配的内存一般存储在堆中,程序结束后内存不会自动释放,需要手工释放
C语言库提供了三个函数进行动态分配内存:
1>malloc
1)malloc(长度) 向内存申请指定的长度的连续空
如果成功:返回的时新申请的内存空间的首地址
失败:返回NULL
malloc函数的返回值为void *类型所以分配非空类型需要强转。比如(int *)malloc(sizeof(int)*元素个数);
代码:
void m_alloc(){ //动态申请20个字节的内存空间,内存空间的首地址放到p中 int *p = (int *)malloc(5*sizeof(int)); //判断是否分配成功 if(p!=NULL){ memset((void *)p,0,sizeof(p)); for (int i=0; i<5; i++) { printf("%d\t",*p++); } printf("\n"); //如果成功,可以存放数据了 *p = 1; *(p+1) = 10; *(p+2) = 100; *(p+3) = 1000; *(p+4) = 10000; for (int i=0; i<5; i++) { printf("%d\t",*p++); } }else{ printf("内存分配失败!"); } }
注意:
1)malloc() 申请的空间,如果不初始化,存放的也是垃圾数
2)进行初始化 memset(地址,用什么初始化,长度);
2> calloc
calloc(4,4) 第一个4,申请几块 第二个4 每一块的长度4 calloc(10,sizeof(int));
void c_alloc(){ // (void *) 分5块 每块的大小 char *p = (char *)calloc(5, sizeof(char)); char *p1=p; // 判断是否成功 if (p!=NULL) { // for (int i=0; i<5; i++) { // printf("%d\t",*p++); // } printf("\n"); for (int i=0; i<5; i++,p++) { *p=65+i; } // *p = ‘A‘; // *(p+1)=65; // *(p+2)=‘a‘; // *(p+3)=‘z‘; // *(p+4)=‘x‘; for (int i=0; i<5; i++) { printf("%c\t",*p1++); } } }
经常用来申请数组的空间
注意: calloc 可以帮我们自动初始化为0
3>realloc
realloc(地址,新的长度) 重新修改大小后,让原指针重新指向一次 p = (int *)realloc(p,100);
void re_alloc(){ // (void *) 分5块 每块的大小 char *p = (char *)calloc(5, sizeof(char)); char *p1=p; // 判断是否成功 if (p!=NULL) { for (int i=0; i<5; i++,p++) { *p=65+i; } // A B C D E //重新修改大小以后,重新指向一次 p1 = realloc(p1, 7*sizeof(char)); *(p1+5)=‘a‘; *(p1+6)=‘b‘; for (int i=0; i<7; i++) { printf("%c\t",*p1++); } }
4)free();
为什么要使用free()
如果不使用free释放掉我们自己申请的内存空间,有可能会造成内存泄露
free 释放存储空间
int *p = (int *)malloc(12);
free(p); //释放
*p = 10; (错误的)因为p所指向的内存空间已经被释放所以*p所指向的内存空间不能赋值操作,一般我们要讲指针为空 p = NULL;