学习Nisy的C教程第30课后写的通讯录程序,欢迎来查错
学习Nisy的C教程第30课后,写了个通讯录程序,用tc2编译成功,运行时末尾有一行提示:Null pointer assignment
改用vc6编译,运行正常。不知问题出在哪里,请大家帮忙分析分析,谢谢。
(感谢扎西,现已添加了一些注释)
/* list3.h -- 通讯录头文件 */
/* 本通讯录的联系人姓名和手机号码串可任意长度 */
#define NULL 0
typedef struct
{
char *name; /* 联系人姓名 */
char *phone; /* 手机号码 */
}Contacts;
#define ElementType Contacts
/* #define ElementType char */
typedef struct
{
ElementType *pbuffer;
int nlen; /* 当前联系人数量 */
int nmax; /* 联系人数量上限 */
}List;
/* 初始化 */
List * InitList(int n);
/* 清除通讯录 */
int DestroyList(List * lp);
/* 追加联系人 */
int AppendList(List * lp, ElementType *data);
/* 插入联系人 */
int InsertList(List * lp, ElementType *data, int n);
/* 删除联系人 */
int DeleteList(List * lp, int n);
/* 遍历联系人 */
int TraverseList(List * lp, void (*f)(ElementType *pdata));
/* 读取一个联系人 */
int GetElement(List * lp, ElementType *pdata, int n);
/* list3.c -- 通讯录文件 */
/* 本通讯录的联系人姓名和手机号码串可任意长度 */
#include"List3.h"
/* 初始化通讯录 */
List * InitList(int n)
{
List * lp = NULL;
lp = (List *)malloc(sizeof(List));
if(!lp)
{
return lp;
}
lp->pbuffer = (ElementType *)malloc(sizeof(ElementType) * n);
if (!lp->pbuffer)
{
free(lp);
lp = NULL;
return lp;
}
lp->nmax = n;
lp->nlen = 0;
return lp;
}
/* 清除通讯录 */
int DestroyList(List * lp)
{
int i;
if (lp)
{
for (i = 0; i < lp->nlen; i++)
{
if (lp->pbuffer.name) free(lp->pbuffer.name);
if (lp->pbuffer.phone) free(lp->pbuffer.phone);
}
/* if (lp->pbuffer) free(lp->pbuffer); */
if (lp) free(lp);
}
return 1;
}
/* 追加联系人 */
int AppendList(List * lp, ElementType *pdata)
{
int nlen;
if (lp->nlen >= lp->nmax)
{
printf("\nList is already full!\n");
return 0;
}
/* 每个联系人单独申请空间,这样联系人姓名和手机号就可以不限定长度了 */
nlen = strlen(pdata->name);
lp->pbuffer.name = (char *)malloc(nlen + 1);
if (!(lp->pbuffer.name))
{
return 0;
}
memset(lp->pbuffer.name, 0, nlen + 1);
nlen = strlen(pdata->phone);
lp->pbuffer.phone = (char *)malloc(nlen + 1);
if (!(lp->pbuffer.phone))
{
free(lp->pbuffer.name);
return 0;
}
memset(lp->pbuffer.phone, 0, nlen + 1);
/* 不是引用地址而是复制姓名和手机号,便于循环动态追加 */
strcpy(lp->pbuffer.name, pdata->name);
strcpy(lp->pbuffer.phone, pdata->phone);
lp->nlen++;
return lp->nlen;
}
/* 插入联系人 n=1,2,3,...*/
int InsertList(List * lp, ElementType *pdata, int n)
{
int i;
int nlen;
if (lp->nlen >= lp->nmax)
{
printf("\nList is already full!\n");
return 0;
}
if (n <= 0 || n > lp->nlen)
{
printf("\nThe position to insert is out of List!\n");
return 0;
}
for (i = lp->nlen; i >= n; i--)
{
memcpy(&lp->pbuffer, &lp->pbuffer, sizeof(ElementType));
}
/* memcpy(&lp->pbuffer, pdata, sizeof(ElementType)); */
/* 每个联系人单独申请空间,这样联系人姓名和手机号就可以不限定长度了 */
nlen = strlen(pdata->name);
lp->pbuffer.name = (char *)malloc(nlen + 1);
if (!(lp->pbuffer.name))
{
return 0;
}
memset(lp->pbuffer.name, 0, nlen + 1);
nlen = strlen(pdata->phone);
lp->pbuffer.phone = (char *)malloc(nlen + 1);
if (!(lp->pbuffer.phone))
{
free(lp->pbuffer.name);
return 0;
}
memset(lp->pbuffer.phone, 0, nlen + 1);
/* 不是引用地址而是复制姓名和手机号,便于循环动态插入 */
strcpy(lp->pbuffer.name, pdata->name);
strcpy(lp->pbuffer.phone, pdata->phone);
lp->nlen++;
return lp->nlen;
}
/* 删除联系人n=1,2,3,...*/
int DeleteList(List * lp, int n)
{
int i;
if (lp->nlen <= 0)
{
printf("\nYou can't delete because List is Empty!\n");
return 0;
}
if (n <= 0 || n > lp->nlen)
{
printf("\nThe position to delete is out of List!\n");
return 0;
}
/* 先释放该联系人占用的内存 */
if(lp->pbuffer.name) free(lp->pbuffer.name);
if(lp->pbuffer.phone) free(lp->pbuffer.phone);
/* 再将其后的联系人信息的指针逐个往前复制 */
for (i = n - 1; i < lp->nlen; i++)
{
memcpy(&lp->pbuffer, &lp->pbuffer, sizeof(ElementType));
}
/* 原末尾的联系人姓名、手机号处的指针清除 */
lp->pbuffer.name = NULL;
lp->pbuffer.phone = NULL;
/* memset(&lp->pbuffer, 0, sizeof(ElementType)); */
lp->nlen--;
return lp->nlen;
}
/* 遍历联系人 */
int TraverseList(List * lp, void (*f)(ElementType *pdata))
{
int i;
if (lp->nlen == 0)
{
printf("\nList is Empty!\n");
return 0;
}
for (i = 0; i < lp->nlen; i++)
{
f(&lp->pbuffer);
}
printf("\n");
return 1;
}
/* 读取一条联系人记录n=1,2,3,... */
int GetElement(List * lp, ElementType *pdata, int n)
{
if (n <= 0 || n > lp->nlen)
{
printf("\nThe position to delete is out of List!\n");
return 0;
}
memcpy(pdata, &lp->pbuffer, sizeof(ElementType));
return 1;
}
/* test3.c -- 通讯录文件 */
/* 和list3.c一起编译 */
/* 本通讯录的联系人姓名和手机号码串可任意长度 */
#include "List3.h"
void myprintf(ElementType * pdata)
{
printf("{%s, %s}\n", pdata->name, pdata->phone);
}
int main()
{
int i;
List *lp = InitList(9);
ElementType str[] = {
{"AAAAAA","11111111111"},
{"BBBBBB","22222222222"},
{"CCCCCC","33333333333"},
{"DDDDDD","44444444444"},
{"EEEEEE","55555555555"},
{"FFFFFF","66666666666"},
{"GGGGGG","77777777777"},
{"HHHHHH","88888888888"},
{"IIIIII","99999999999"},
};
ElementType data = {"KKKKKK","12345678901"};
if(!lp)
{
printf("\nInitList error!\n");
return 0;
}
for (i = 0; i < 9; i++)
{
AppendList(lp, str+i);
}
/* 以上改为运行时循环输入联系人信息。这里为简化示例才固定初始化信息 */
TraverseList(lp, myprintf);
/* 以下可改为菜单选择动态追加、插入、删除、检索、清除。*/
DeleteList(lp, 3);
TraverseList(lp, myprintf);
DeleteList(lp, 3);
TraverseList(lp, myprintf);
GetElement(lp, &data, 3);
myprintf(&data);
printf("\n");
AppendList(lp, &data);
TraverseList(lp, myprintf);
InsertList(lp, &data, 1);
TraverseList(lp, myprintf);
AppendList(lp, &data);
TraverseList(lp, myprintf);
DestroyList(lp);/* 用tc2编译的运行时这里提示 "Null pointer assignment" ,请找出错在哪里*/
return 1;
}
学的好快呀~我才看到第7课~而且菱形代码还没有实现,正在努力思考ing~
页:
[1]