【问题描述】:
前面我们完成了一个简易的通讯录,可以实现联系人的增删改查等基本功能,但在存储方面,只能支持静态的1000人的存储量,这样一来,如果联系人比较少,则会造成较大的内存浪费,联系人超过一千时,就不能完成存储了,所以接下来我们要做的一个操作就是将之前的通讯录改为一个支持动态扩容的版本。
【问题思考】:
1、说到动态扩容,我们可以想到,能够使用malloc来完成首次申请内存空间,第一次申请的内存空间不足时,进行扩容,可以使用relloc或者malloc来完成。使用malloc进行扩容时, 需要我们手动来进行原数据搬运及原内存释放。
2、需要修改哪些部分?初始化模块和新增联系人模块。
【实现代码】:
1、宏及初始化部分
删除掉之前固定的内存宏定义
typedef struct PersonInfo {
char name[1024];//姓名
char sex[1024];//性别
char age[1024];//年龄
char phone[1024];//电话
char address[1024];//住址
}PersonInfo;
typedef struct AddressBook {
PersonInfo* persons;
int size;//[0,size)
int capacity;//最大容量
}AddressBook;
AddressBook g_address_book;
void Init() {
g_address_book.size = 0;
g_address_book.capacity = 100;
g_address_book.persons = (PersonInfo*)malloc(sizeof(PersonInfo) * g_address_book.capacity);
for (int i = 0; i < g_address_book.capacity; ++i) {
g_address_book.persons[i].name[0] = '\0';
g_address_book.persons[i].sex[0] = '\0';
g_address_book.persons[i].age[0] = '\0';
g_address_book.persons[i].phone[0] = '\0';
g_address_book.persons[i].address[0] = '\0';
}
}
2、新增模块
void AddPersonInfo() {
printf("新增联系人\n");
if (g_address_book.size >= g_address_book.capacity) {
printf("当前空间不足,进行扩容\n");
g_address_book.capacity += 100;
PersonInfo* p = (PersonInfo*)malloc(sizeof(PersonInfo)*g_address_book.capacity);
for (int i = 0; i < g_address_book.size; ++i) {
p[i] = g_address_book.persons[i];//原数据搬运
}
free(g_address_book.persons);//释放原内存空间
g_address_book.persons = p;
}
PersonInfo* person_info = &g_address_book.persons[g_address_book.size];
printf("请输入联系人姓名:");
scanf("%s",person_info->name);
printf("请输入联系人性别:");
scanf("%s", person_info->sex);
printf("请输入联系人年龄:");
scanf("%s", person_info->age);
printf("请输入联系人电话:");
scanf("%s", person_info->phone);
printf("请输入联系人住址:");
scanf("%s", person_info->address);
++g_address_book.size;
printf("新增联系人成功!\n");
}
其它部分与之前一样,这样的修改完成后,我们就可以得到一个支持动态扩容的通讯录了。