长沙网站建设公司排名,网站备案承诺书怎么写,网站建设需要注意哪些内容,网站制作报价是否合法文章目录 一、动态内存函数1. malloc2. calloc3. realloc4. free 二、常见的错误1.malloc或calloc开辟的空间未检查2.越界访问3.对非malloc和calloc开辟的空间#xff0c;用free释放4.对同一块动态内存多次释放5.用free释放动态内存的一部分 三、通讯录(动态版本改写)总结 一、… 文章目录 一、动态内存函数1. malloc2. calloc3. realloc4. free 二、常见的错误1.malloc或calloc开辟的空间未检查2.越界访问3.对非malloc和calloc开辟的空间用free释放4.对同一块动态内存多次释放5.用free释放动态内存的一部分 三、通讯录(动态版本改写)总结 一、动态内存函数
要介绍动态内存函数我们就要知道动态内存函数开辟的空间在内存的什么位置。 如下图所示 动态内存函数开辟的空间在堆区该区域的空间只有free函数和程序结束才会释放。
1. malloc
函数的声明void* malloc (size_t size)包含在stdlib.h头文件中。 调用该函数可以向内存中申请大小为size个字节的连续空间并返回该空间的起始地址。 注意
如果malloc开辟空间成功则返回成功开辟好空间的起始地址如果malloc开辟空间失败则返回NULL不要开辟大小为0的空间这是标准未定义的。
因此malloc开辟空间后我们要检查返回值。
#include stdio.h
#include stdlib.hint main()
{int* pa (int*)malloc(sizeof(int) * 10);//开辟大小为40个字节的空间//检查是否空间开辟失败if (pa NULL){exit(-1);}free(pa);pa NULL;return 0;
}2. calloc
函数的声明void* calloc (size_t num, size_t size)包含在stdlib.h头文件中。 调用该函数可以向内存中申请num个大小是size个字节的连续空间再将空间每一个字节初始化为0并返回该空间的起始地址。 calloc与malloc的唯一区别在于calloc会将空间每一个字节初始化为0。 如下所示
#include stdio.h
#include stdlib.hint main()
{int* arr1 (int*)malloc(sizeof(int) * 10);if (arr1 NULL){exit(-1);}for (int i 0; i 10; i){printf(%d , arr1[i]);}printf(\n);int* arr2 (int*)calloc(sizeof(int), 10);if (arr2 NULL){exit(-1);}for (int i 0; i 10; i){printf(%d , arr2[i]);}free(arr1);free(arr2);arr1 NULL;arr2 NULL;return 0;
}3. realloc
函数的声明void* realloc (void* ptr, size_t size)包含在stdlib.h头文件中。 调用该函数可以调整由malloc和calloc开辟的空间大小调整为size个字节大小的空间。 但要注意其调整空间大小的方式有两种原地扩容和异地扩容。 原地扩容原地址空间后空间大小充足在原地址空间直接扩容。 异地扩容原地址空间后空间大小不够在堆区另找一片充足的空间使用。 如果调整的大小过大realloc会返回NULL。
//异地扩容
int main()
{int* pa (int*)malloc(sizeof(int) * 10);if (pa NULL){exit(-1);}printf(%p\n, pa);int* tmp (int*)realloc(pa, sizeof(int) * 20);if (tmp ! NULL){pa tmp;printf(%p\n, pa);}free(pa);pa NULL;return 0;
}//原地扩容
int main()
{char* pa (char*)malloc(sizeof(char) * 10);if (pa NULL){exit(-1);}printf(%p\n, pa);char* tmp (char*)realloc(pa, sizeof(char) * 20);if (tmp ! NULL){pa tmp;printf(%p\n, pa);}free(pa);pa NULL;return 0;
}4. free
函数的声明void free (void* ptr)包含在stdlib.h头文件中。 调用该函数可以释放由malloc和calloc开辟的空间指针变量ptr本身内容不变需要程序员本身置空。
如果ptr是NULL则函数什么事都不会做如果ptr并不是malloc和calloc开辟的空间那free函数的行为未定义
如下
int main()
{int* pa (int*)malloc(sizeof(int) * 10);if (pa NULL){exit(-1);}free(pa);//释放pa所指向的空间pa NULL;//pa置NULL防止野指针return 0;
}二、常见的错误
1.malloc或calloc开辟的空间未检查
有时开辟空间过大而未检查时会发生对NULL的解引用 int main()
{int* pa (int*)malloc(sizeof(int) * INT_MAX);*pa 10;free(pa);pa NULL;return 0;
}2.越界访问
访问超出开辟空间大小
int main()
{int* pa (int*)malloc(sizeof(int) * 10);if (pa NULL){exit(-1);}for (int i 0; i 11; i){pa[i] 0;}free(pa);pa NULL;return 0;
}3.对非malloc和calloc开辟的空间用free释放
free函数只能用了释放动态内存空间
int main()
{int arr[10] { 0 };free(arr);return 0;
}4.对同一块动态内存多次释放
动态内存空间释放一次即可
int main()
{int* pa (int*)malloc(sizeof(int) * 10);if (pa NULL){exit(-1);}free(pa);free(pa);pa NULL;return 0;
}5.用free释放动态内存的一部分
开辟的动态内存空间实际大小要大于我们申请的大小那多出的一部分空间要记录我们这次申请空间的信息free函数就可以根据这一部分信息来释放我们申请的空间大小。如果我们传递的指针并未指向空间首地址那么free就找不到信息来释放空间。
int main()
{int* pa (int*)malloc(sizeof(int) * 10);if (pa NULL){exit(-1);}pa;free(pa);pa NULL;return 0;
}三、通讯录(动态版本改写)
静态版本通讯录 相对于静态版本而言动态版本改变并不多也不难下面就是要改变的部分。
结构
//动态版本
typedef struct Contact
{PeoInfo* data;int sz;//记录此时已用的大小int capacity;//记录通讯录的大小
}Contact;2.初始化InitContact
#define INITSIZE 10//初始化通讯录
void InitContact(Contact* pc)
{pc-sz 0;pc-capacity INITSIZE;pc-data (PeoInfo*)malloc(sizeof(PeoInfo) * INITSIZE);if (pc-data NULL){perror(malloc);return;}
}扩容AddCapacity
bool AddCapacity(Contact* pc)
{PeoInfo* tmp realloc(pc-data, sizeof(PeoInfo) * (pc-capacity) * 2);if (tmp NULL){perror(realloc);return false;}pc-data tmp;pc-capacity * 2;return true;
}//添加联系人
void AddContact(Contact* pc)
{assert(pc);if (pc-sz pc-capacity){if (AddCapacity(pc) true){printf(扩容成功\n);}else{printf(扩容失败\n);return;}}printf(请输入联系人名字:);scanf(%s, pc-data[pc-sz].name);printf(请输入联系人性别:);scanf(%s, pc-data[pc-sz].sex);printf(请输入联系人年龄:);scanf(%d, (pc-data[pc-sz].age));printf(请输入联系人电话:);scanf(%s, pc-data[pc-sz].tele);printf(请输入联系人地址:);scanf(%s, pc-data[pc-sz].adder);pc-sz 1;
}退出ExitContact
//退出通讯录
void ExitContact(Contact* pc)
{free(pc-data);pc-data NULL;pc-sz 0;pc-capacity 0;
}总结
以上就是我对于动态内存管理的了解和应用。