问题:
之前实现的通讯录在存储方面只能支持静态的200人的存储量,如果联系人较少,则会造成较大的内存浪费,联系人较多时,就不能完成存储。可以通过将通讯录改成动态扩容版本。
思考:
动态扩容,我们可以使用malloc完成首次申请内存空间,第一次内存空间不足时,进行扩容,可以使用relloc或则malloc完成。需要修改初始化模块和新增联系人模块。
删除之前固定的内存宏定义
#define NAME_MAX_SIZE 1024
#define PHONE_MAX_SIZE 100
#define SEX_MAX_SIZE 100
#define AGE_MAX_SIZE 100
#define ADDRESS_MAX_SIZE 1024
typedef struct PersonInfo
{
char name[NAME_MAX_SIZE];
char phone[PHONE_MAX_SIZE];
char sex[SEX_MAX_SIZE];
char age[AGE_MAX_SIZE];
char address[ADDRESS_MAX_SIZE];
}PersonInfo;
typedef struct AddrBook
{
PersonInfo *persons;
int size;//当前数组中有效元素的个数
int capacity;//当前数组的最大容量
}AddrBook;
void Init(AddrBook* addr_book)
{
assert(addr_book != NULL);
addr_book->size = 0;
addr_book->capacity = 100;
addr_book->persons = (PersonInfo*)malloc(sizeof(PersonInfo)*addr_book->capacity);
for (int i = 0; i <addr_book->capacity; ++i)
{
memset(addr_book->persons[i].name, 0, NAME_MAX_SIZE);
memset(addr_book->persons[i].phone, 0, PHONE_MAX_SIZE);
memset(addr_book->persons[i].age, 0, AGE_MAX_SIZE);
memset(addr_book->persons[i].sex, 0, SEX_MAX_SIZE);
memset(addr_book->persons[i].address, 0, ADDRESS_MAX_SIZE);
}
}
新增联系人模块
void Add(AddrBook* addr_book)
{
assert(addr_book != NULL);
printf("新增联系人!\n");
if (addr_book->size >= addr_book->capacity)
{
addr_book->capacity += 100;
addr_book->persons =(PersonInfo*)realloc(addr_book->persons, addr_book->capacity);
}
PersonInfo*p = &addr_book->persons[addr_book->size];
printf("请输入新增联系人的姓名:");
scanf("%s", p->name);
printf("请输入新增联系人的电话:");
scanf("%s", p->phone);
printf("请输入新增联系人的性别:");
scanf("%s", p->sex);
printf("请输入新增联系人的年龄:");
scanf("%s", p->age);
printf("请输入新增联系人的地址:");
scanf("%s", p->address);
++addr_book->size;
}
练习动态内存开辟 malloc calloc realloc
malloc
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
int main()
{
int arr[10] = { 0 };//连续的 栈
int *p = (int*)malloc(sizeof(int)* 10);//连续的 堆
assert(p != NULL);
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
free(p);//释放所指动态内存,避免内存泄漏
p = NULL;//避免野指针
system("pause");
return 0;
}
calloc
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//void* calloc(size_t num,size_t size)
int main()
{
int *p = calloc(10, sizeof(int));
assert(p != NULL);
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
free(p);
p = NULL;
system("pause");
return 0;
}
realloc
void* realloc(void* ptr, size_t size)
{
int*p =(int*) realloc(p, sizeof(int)* 10 * 2);
assert(p != NULL);
free(p);
p = NULL;
return 0;
}