free(p);//释放内存
p = NULL;//软件工程规范,释放内存以后,指针应该赋值为空
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 //内存不可以反复释放,内存释放以后不可以引用,否则会出现垃圾数据 6 //内存释放以后,指针应该赋值为空,就可以规避再次引用,以及反复释放的问题 7 8 void check(int *px) 9 { 10 int i; 11 for (i = 0;i < 5;i++)//循环遍历 12 { 13 if (px[i] < 60)//抓不及格 14 { 15 printf("%d ", px[i]); 16 } 17 } 18 } 19 20 main() 21 { 22 int num; 23 int i; 24 scanf("%d", &num); 25 printf("num=%d ", num); 26 27 int *p = (int *)malloc(sizeof(int)*num); 28 29 if (p == NULL) 30 { 31 printf("fail"); 32 } 33 else 34 { 35 printf("succes "); 36 for (i = 0;i < num;i++) 37 { 38 p[i] = i; 39 printf("%d ", p[i]); 40 } 41 printf("p=%x ", p); 42 43 free(p);//释放内存 44 p = NULL;//软件工程规范,释放内存以后,指针应该赋值为空 45 46 printf("p=%x ", p);//内存释放以后,指针的值并不发生变化 47 printf("%d ", p[2]);//如果再次引用指针,就会出现垃圾数值 48 //如果指针为空,软件测试的时候就可以快速定位错误,否则的话,就会留下软件故障的隐患 49 } 50 51 system("pause"); 52 }
建立动态数组,输入5个学生的成绩,另外用一个函数检查其中有无低于60,输出不及格的成绩
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 void check(int *px) 7 { 8 int i; 9 for (i = 0;i < 5;i++)//循环遍历 10 { 11 if (px[i] < 60)//抓不及格 12 { 13 printf("%d ", px[i]); 14 } 15 } 16 } 17 18 main() 19 { 20 int *p = (int *)malloc(sizeof(int) * 5); 21 int i; 22 23 for (i = 0;i < 5;i++) 24 { 25 scanf("%d", &p[i]); 26 } 27 28 printf(" "); 29 check(p); 30 31 system("pause"); 32 }
malloc,calloc都是分配内存,malloc根据大小,calloc根据元素大小还有个数
malloc分配后不会初始化,calloc会自动初始化为0
realloc就是内存不够用的情况下,拓展内存。如果原来的内存后部无人使用,就直接拓展。有人使用,就重新分配,并且先复制原来内存的内容,然后回收原来的内存
malloc函数
malloc函数返回值的类型为void *,函数的调用形式为:malloc(size);
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int num; 9 int i; 10 scanf("%d", &num); 11 printf("num=%d ", num); 12 13 int *p = (int *)malloc(sizeof(int)*num); 14 15 printf("%x ", p); 16 17 if (p == NULL) 18 { 19 printf("fail"); 20 21 } 22 else 23 { 24 printf("succes "); 25 for (i = 0;i < num;i++) 26 { 27 p[i] = i; 28 printf("%d ", p[i]); 29 } 30 free(p); 31 } 32 33 system("pause"); 34 }
calloc函数
calloc函数返回值的类型为void *,函数的调用形式为:calloc(n, size);
通过调用calloc函数所分配的存储单元,系统自动置初值为0
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int num; 9 int i; 10 scanf("%d", &num); 11 printf("num=%d ", num); 12 13 int *p = (int *)calloc(num, sizeof(int)); 14 15 printf("%x ", p); 16 17 if (p == NULL) 18 { 19 printf("fail"); 20 21 } 22 else 23 { 24 printf("succes "); 25 for (i = 0;i < num;i++) 26 { 27 p[i] = i; 28 printf("%d ", p[i]); 29 } 30 free(p); 31 } 32 33 system("pause"); 34 }
realloc函数
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 main() 7 { 8 int num, addnum; 9 int i; 10 scanf("%d %d", &num, &addnum); 11 printf("num=%d,addnum=%d ", num, addnum); 12 13 int *p = (int *)malloc(sizeof(int)*num); 14 15 if (p == NULL) 16 { 17 printf("fail"); 18 } 19 else 20 { 21 printf("succes "); 22 for (i = 0;i < num;i++) 23 { 24 p[i] = i; 25 printf("%d ", p[i]); 26 } 27 //重新分配内存,如果可以拓展就拓展,否则就重新分配 28 //拓展就是原来地址后面增加内存 29 //不够的情况下,就回收原来的内存,并在回收之前分配一片内存,将原来的内存复制过来 30 int *px = realloc((void *)p, sizeof(int)*(addnum + num)); 31 for (i = num;i < num + addnum;i++) 32 { 33 px[i] = i; 34 printf("%d ", px[i]); 35 } 36 free(px); 37 } 38 39 40 system("pause"); 41 }
define和const区别
1 #define _CRT_SECURE_NO_WARNINGS 2 3 #include<stdio.h> 4 #include<stdlib.h> 5 6 #define N 20 7 8 main() 9 { 10 int a[N]; 11 12 //printf("%x", &N);编译器放在常量区,没有地址,无从修改 13 14 const int num = 10;//可变的常量,可以强制去掉常量的属性 15 16 printf("%x", &num); 17 18 system("pause"); 19 }
传统数组的缺点:
1 数组长度必须事先制定,且只能是常整数,不能是变量。
1 #include<stdio.h> 2 main() 3 { 4 int a[5]; /* OK */ 5 6 int len = 5; /* error */ 7 int a[len]; 8 }
2 传统形式定义的数组,该数组的内存程序员无法手动释放。
在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会被系统释放。
3 数组的长度一旦定义,其长度就不能再更改。
数组的长度不能在函数运行的过程中动态的扩充或缩小。
4 A函数定义的数组,在A函数运行期间可以被其他函数使用,但A函数运行完毕之后,A函数中的数组将无法再被其他函数使用。
传统方式定义的数组不能跨函数使用。
1 #include<stdio.h> 2 main() 3 { 4 int i = 5; /* 分配了4个字节,静态分配 */ 5 6 int * p = (int *)malloc(4); 7 /* 8 malloc函数只有一个形参,并且形参是整型 9 4表示请求系统为本程序分配4个字节 10 malloc函数只能返回第一个字节的地址 11 上述语句分配了8个字节,p变量占4个字节,p所指向的内存也占4个字节 12 p本身所占的内存是静态分配的,p所指向的内存是动态分配的 13 */ 14 15 free(p); 16 /* 17 表示把p所指向的内存给释放掉 18 p本身的内存是静态的,不能由程序员手动释放,p本身的内存只能在p变量所在的函数运行终止时由系统自动释放 19 */ 20 }
动态一维数组
1 #include<stdio.h> 2 main() 3 { 4 int i; 5 int len; 6 int * parr; 7 8 printf("请输入你要存放的元素的个数: "); 9 scanf("%d", &len); 10 11 parr = (int *)malloc(4 * len); 12 13 printf("请输入你要存放的元素: "); 14 for (i = 0;i < len;++i) 15 { 16 scanf("%d", &parr[i]); 17 } 18 19 printf("一维数组的内容是: "); 20 for (i = 0;i < len;++i) 21 { 22 printf("%d ", parr[i]); 23 } 24 }
动态内存和静态内存的比较:
静态内存是有系统自动分配,由系统自动释放。
静态内存是在栈分配的。
动态内存是由程序员手动分配,手动释放。
动态内存是在堆分配的。