今天在学习链表时,参考了一篇博客来学习C++中的链表,然而在最后运行最后的程序:
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef struct data
{
int number;
string name;
string sex;
}data;
typedef struct listpoint
{
data *information;
listpoint *next;
listpoint *last;
listpoint *branch;
}listpoint;
/********************************************************/
listpoint *create_normal_list(int n)
{
listpoint *head,*normal,*end;
head=(listpoint*)malloc(sizeof(listpoint));
head->information=(data*)malloc(sizeof(data));
end=head;
for(int i=0;i<n;i++)
{
normal=(listpoint*)malloc(sizeof(listpoint));
normal->information=(data*)malloc(sizeof(data));
cout<<"input the number :";
cin>>normal->information->number;
cout<<"input the name :";
cin>>normal->information->name;
cout<<"input the sex :";
cin>>normal->information->sex;
cout<<"----------------------------------"<<endl;
end->next=normal;
normal->last=end;
end=normal;
}
end->next=NULL;
head->last=NULL;
return head;
}
listpoint *create_loop_list(int n)
{
listpoint *head,*normal,*end;
head=(listpoint*)malloc(sizeof(listpoint));
head->information=(data*)malloc(sizeof(data));
end=head;
for(int i=0;i<n;i++)
{
normal=(listpoint*)malloc(sizeof(listpoint));
normal->information=(data*)malloc(sizeof(data));
cout<<"input the number :";
cin>>normal->information->number;
cout<<"input the name :";
cin>>normal->information->name;
cout<<"input the sex :";
cin>>normal->information->sex;
cout<<"----------------------------------"<<endl;
end->next=normal;
normal->last=end;
end=normal;
}
end->next=head;
head->last=end;
return head;
}
listpoint *create_random_branch_list(int n)
{
listpoint *search_point(listpoint *list,int n);
listpoint *head;
head=create_normal_list(n);
listpoint *p,*bp;
p=head;
srand((int)(time(NULL)));
int randnum;
while((p=p->next)!=NULL)
{
randnum=rand()%n+1;
bp=search_point(head,randnum);
p->branch=bp;
}
return head;
}
listpoint *create_random_sort_list(int n)
{
listpoint *head;
head=create_normal_list(n);
listpoint *p1,*p2;
int n1=0;
int n2=n;
srand((int)(time(NULL)));
int randnum;
while(n2!=1)
{
p1=head;
p2=head;
randnum=rand()%n2+1+n1;
for(int i=0;i<randnum;i++)
{p2=p2->next;}
for(int i=0;i<n1;i++)
{p1=p1->next;}
if(randnum==n)
{
p2->last->next=NULL;
}
else
{
p2->next->last=p2->last;
p2->last->next=p2->next;
}
p1->next->last=p2;
p2->next=p1->next;
p1->next=p2;
p2->last=p1;
n1+=1;
n2-=1;
}
return head;
}
/********************************************************/
void change_point(listpoint *list,int n,data *ifmation)
{
listpoint *p;
p=list;
for(int i=0;i<n;i++)
{
p=p->next;
}
p->information=ifmation;
}
void delete_point(listpoint *list,int n)
{
listpoint *p;
p=list;
for(int i=0;i<n;i++)
{
p=p->next;
}
p->last->next=p->next;
p->next->last=p->last;
free(p);
}
void insert_point(listpoint *list,int n,data *ifmation)
{
listpoint *p;
p=list;
for(int i=0;i<n-1;i++)
{
p=p->next;
}
listpoint *insertpoint;
insertpoint=(listpoint*)malloc(sizeof(listpoint));
insertpoint->information=ifmation;
insertpoint->next=p->next;
p->next->last=insertpoint;
p->next=insertpoint;
insertpoint->last=p;
}
listpoint *search_point(listpoint *list,int n)
{
listpoint *p;
p=list;
for(int i=0;i<n;i++)
{
p=p->next;
}
return p;
}
void output_point(listpoint *point)
{
cout<<"the number is :"<<point->information->number<<endl;
cout<<"the name is :"<<point->information->name<<endl;
cout<<"the sex is :"<<point->information->sex<<endl;
cout<<"----------------------------------"<<endl;
}
void output_list(listpoint *point)
{
listpoint *p;
p=point;
cout<<endl<<endl<<endl;
while((p=p->next)!=NULL)
{
output_point(p);
}
}
void output_list_part(listpoint *list,int m,int n)
{
int difference=n-m;
listpoint *p;
p=list;
cout<<endl<<endl<<endl;
for(int i=0;i<m;i++)
{
p=p->next;
}
for(int i=0;i<difference+1;i++)
{
output_point(p);
p=p->next;
}
}
/***************************************************************/
int main()
{
listpoint *head;
head=create_random_sort_list(7);
output_list(head);
system("pause");
return 0;
}
出现了以下报错:
经过查询以及请教计算机的同学,发现问题出在malloc函数上,malloc函数是C中分配内存的函数,而string是C++中新增的类(C中是没有类这一概念的),于是用malloc函数给含有string类的data型结构体申请内存时,出现了报错。
因此,想要不报错,需要使用C++中的new来分配内存,函数应该将程序中的 normal1 = (datas*)malloc(sizeof(datas));
修改为normal1 = new datas;
。在修改后,就不报错了,程序运行成功。
下面附上我测试的程序:
#include<iostream>
#include<cstdlib>
#include<cstring>
typedef struct data
{
int number;
string name;
string sex;
}datas;
typedef struct listpoint
{
datas* information;
listpoint* next;
listpoint* last;
listpoint* branch;
}listpoint;
int main()
{
datas* normal1,normal2;
//normal1中的name和sex可正确赋值
normal1 = new datas;
normal1->number = 15;
normal1->name = "Mike";
normal1->sex = "Man";
cout << normal1->number << endl;
cout << normal1->name << endl;
cout << normal1->sex << endl;
//normal2中赋值报错
normal2 = (datas*)malloc(sizeof(datas));
normal2->number = 16;
normal2->name = "Tom";
normal2->sex = "Man";
cout << normal2->number << endl;
cout << normal2->name << endl;
cout << normal2->sex << endl;
return 0;
}
总结(引自另一篇参考博客):
- malloc只是负责申请一块内存,没有任何其他动作。
- 直接声明结构体或者new 一个结构体指针,会调用默认构造函数。如果结构中包含类,同样会调用成员类的默认构造函数。
- 程序中的内存错误是因为使用malloc分配一个结构体内存,但是string是一个类。并没有调用string的构造函数,所以string在malloc之后没有正确构造,导致使用时段错误。
所以C++应该用new和delete,C语言用malloc和free,这样才不容易出错,以后应该多加注意。
(另外,C++链表参考博客中的结构体定义方式也是C语言的方式,和C++的定义方式不同,而C与C++中结构体定义方式的对比,可参考博客:struct和typedef struct彻底明白了 && C语言结构体)