// 动态内存分配的目的:合理的使用内存(内存是有限的)
// 存储区的划分
// 1,栈区:存储是以栈(先进后出)的结构存储,局部变量(在函数内部定义的变量)和形式参数(函数的参数)存放到栈区,调用函数的时候,为局部变量和形式参数分配内存,调出函数后,系统收回为这个函数分配的内存
// 2,堆区:是由开发人员手动申请,手动释放,需要人工管理
// 3,静态区(全局区):全局变量(定义在函数外部的变量)和静态变量(有static修饰的变量),存放在静态区,一旦开辟内存空间,就不会释放,直到程序结束
// 4,常量区:存储:整型常量,字符常量,浮点常量,字符串常量,常量区的内容不能被修改
// 5,代码区:存放CPU指令
// int x = 10, y = 5;
// int result = maxValue(x, y);
// printf("%s", getString());//无输出,调用之前函数已经被系统回收
//
// printf("%p
", &x);//栈区 0x7fff5fbff84c
// static int i = 4;
// printf("%p
", &i);//静态区 0x100001024
// char *p = "aaa";
// printf("%p
", p);//常量区 0x100000f94
// 堆区的内存分配
// 手动开辟内存
// void *malloc(size);
// 返回值类型:void*,泛类型,可以转换成其他类型指针,函数返回的是一个指针
// malloc:函数名
// size:所要分配的内存大小(字节数),无符号整型
char *p = malloc(7);
strcpy(p, "iPhone");
printf("%s
", p);//iPhone
*p = 66;
printf("%s
", p);//BPhone
//
p[3] = ' ';
printf("%s
", p);//BPh
//
//
strcpy(p + 2, "abcde");//越界
printf("%s
", p);
//
strcpy(p, p + 2);//hone
printf("%s
", p);
//
// printf("%c
", *(p + 5));//e
/*
char *p = malloc(7);//栈区分配8个内存空间 在堆区分配7个字节把堆区的首地址存放在栈区内容中,&p是栈区的首地址
strcpy(p, "iPhone"); //常量区分配7个字节拷贝到对应栈区中
printf("%s
", p);//iPhone
printf("%p
", p);
printf("%p
", &p);
char *p1 = "iPhone";//拷贝的是地址 指向常量区 内容不能被修改
char string[] = "iPhone";//拷贝的是内容 拷贝到栈区中,在栈区中的内容是可以被修改的
*/
// for (int i = 0; i < 4; i++) {
// static int a = 0;//只被初始化一次,运行结果1 2 3 4
// a++;
// printf("%d
", a);
// }
//创建一个栈区指针,指向堆区所分配的6个字节的首地址
// int *p = malloc(6);
//把常量区整型常量10,拷贝到堆区前四个字节
// *p = 10;
// p[1] = 20;//error,越界
//free(void *)释放内存函数
// void * :可以接受各种类型的指针
//内存泄露:一块内存一直被占用,得不到释放
//free会把malloc申请是内存释放(重新标记成可用)
// free(p);
//申请一个内存空间随机赋10个整数放在数组中
// int *p = malloc(sizeof(int) * 10);
// for (int i = 0; i < 10; i++) {
// *(p + i) = arc4random() % 21 + 10;
// printf("%d ", *(p + i));
// }
// free(p);
// //释放后p现在还有内容
// p = NULL;//把指针置空
// int *p = malloc(2);//内存泄露
// p = malloc(4);
// free(p);
//有一字符串,其中包含数字,提取其中的数字,要求动态分配内存保存
//提示:先计算出有几个数字,然后根据数字个数来开辟空间
// char string[] = "dfdsfsf2f4gf5hy7g5fd3ds4";
// int i = 0, count = 0;
// while (*(string + i) != ' ') {
// if (*(string + i) <= '9' && *(string + i) >= '0') {
// count++;
// }
// i++;
// }
// char *p = malloc(sizeof(char) * (count + 1));
//
// int k = 0, j = 0;
// while (*(string + k) != ' ') {
// if (*(string + k) >= '0' && *(string + k) <= '9') {
// *(p + j) = *(string + k);
// j++;
// }
// k++;
// }
// //添加结束符
// *(p + j) = ' ';
// printf("%s
", p);
// free(p);
// p = NULL;
//输入3个单词,动态分配内存保存单词,并在最后输出
//提示:定义一个指针数组保存数据 char * word[3] = {0};
// char * words[3] = {0};
// char temp[100] = {0};
// for (int i = 0; i < 3; i++) {
// scanf("%s", temp);
// unsigned long length = strlen(temp) + 1;
// words[i] = malloc(sizeof(char) * length);
// strcpy(words[i], temp);
// }
// for (int i = 0; i < 3; i++) {
// free(words[i]);
// words[i] = NULL;
// }
// void * calloc(n, size);
// 分配n个size大小的内存空间;
// n和size是无符号整型;
// calloc和malloc的区别:calloc会把内存中的数据清零,效率低
// int *p = calloc(5, 4);
// free(p);
// p = NULL;
// void *realloc(p, size)
// 给定一个地址,从这个地址开始,分配size个字节的内存
// p是指针,size是无符号整型
// realloc会先从地址p开始往下找,如果有size个没有使用的字节,就直接标记,并申请;如果发现不够的话,就取堆区的其他地方找一段连续的内存空间,如果找到,就先把之前所申请的内存释放,再把指针指向新找到的内心空间,如果找不到,返回NULL
// int *p = malloc(2);
// printf("%p
", p);
// p = realloc(p, 4);
// printf("%p
", p);
// free(p);
// p = NULL;
// void *memset(void *s, int c, unsigned long n)
// 从s指向的内存开始初始化n个字节的内容为c
// char *p = malloc(5);
// p = memset(p, 66, 10);
// printf("%s
", p);
//void *memcpy(void *dest,const void*source, zize_t n)
// 从source指向的内存开始拷贝到的dest,拷贝n个字节
// char string1[] = "iPhone";
// char string2[] = "ABC";
// memcpy(string1, string2, 2);//ABhone
// memcpy(string1 + 3, string2, 2);//iPhABe
// printf("%s
", string1);
// int memcmp(const void *buf1, const void *buf2, unsigned int count)
// 比较buf1和buf2指向的内存是否相同,比较count个字节
// int *p1 = malloc(4);
// *p1 = 1;
// int *p2 = malloc(8);
// *p2 = 3;
// int result = memcmp(p1, p2, 1);
// printf("%d
", result);
//定义两个指针,分别用malloc,calloc 对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组,如果相同打印Good 否则打印Failed
// int *p1 = malloc(sizeof(int) * 3);
// int *p2 = calloc(3, 4);
// memset(p1, 0, sizeof(int) * 3);
// for (int i = 0; i < 3; i++) {
// *(p1 + i) = arc4random() % 3 + 1;
// *(p2 + i) = arc4random() % 3 + 1;
// }
//
// if (memcmp(p1, p2, sizeof(int) * 3) == 0) {
// printf("Good!
");
// }else{
// printf("Failed...
");
// }
// free(p1);
// p1 = NULL;
// free(p2);
// p2 = NULL;
//