为什么在InsertHash函数中,令一个string等于另一个string时程序就崩溃了

时间:2022-07-23 19:49:45
#include <iostream>
using namespace std;

#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

int a,b;
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a) <(b))
#define LQ(a,b) ((a)> (b))

#define  SUCCESS  1
#define  UNSUCCESS  0
#define  DUPLICATE  -1
#define MAXSIZE 70    //哈希表的长度
#define NULLKEY -1      //空关键字的值
#define DELKEY -2         //被删关键字的值

typedef int KeyType;
typedef int Status;
typedef int ElemType;  
typedef struct HASH{
  KeyType key; 
  string ID; 
  string name;
  string address;  
  struct HASH *next;
  int  count;            //当前数据元素个数
  //int  sizeindex;
               // hashsize[sizeindex]为当前容量
}HASH,*Hash, HashTable[MAXSIZE];

int HAsh(int key){  
    return key%47;  
}

Status InsertHash(HashTable H,int &n,KeyType m,string ID,string na,string add,int p){
//把关键字K插入哈希表
int i,a;
a=HAsh(m);//MOD p取余数 
Hash pre;
if(H[a].key==NULLKEY||H[a].key==DELKEY)
{
H[a].key=m;
H[a].ID=ID;
H[a].name=na;
H[a].address=add;
H[a].count=1;

else//冲突 
{
cout<<" 1"<<endl;
Hash chain_adress;
chain_adress=(Hash)malloc(sizeof(HASH));  
cout<<"4"<<endl;
        chain_adress->key=m;
        cout<<"4"<<endl;
//chain_adress->ID=ID;//此处出现错误
cout<<"4"<<endl;
chain_adress->name=na;
chain_adress->address=add;
cout<<"4"<<endl; 
     chain_adress->next=NULL;

cout<<"2 "<<endl;
   pre = &H[a];  
  
while (pre->next != NULL)  
    pre = pre->next;  
    cout<<"3"<<endl;
   pre->next = chain_adress; 
}
n++;
return OK;
}//InsertHash

template <class Type>  
Type stringToNum(const string& str)  
{  
    istringstream iss(str);  
    Type num;  
    iss >> num;  
    return num;      
}  

Status FileCreateHash(HashTable &H,int n,int m,int p){
//创建哈希表
int i,j,k,l=0;
KeyType id,sum=0;
char x[2]; 
string ID[70],na[70],add[70]; 
for(i=0;i<n;i++)
{
H[i].key=NULLKEY;
H[i].next=NULL;
}
fstream datafile;
datafile.open("IDcard.txt",ios::in);
if(!datafile)
{
cout<<"文件打开失败!"<<endl;
exit(ERROR);
}
for(i=0;i<m;i++)
{
H[i].key=NULLKEY;
//H[i].address=H[i].name=NULL;
H[i].count=0;
 } 
 int *s;
 for(i=0;i<n;i++)
 {
  sum=0;
  datafile>>ID[i]>>na[i]>>add[i];
  cout<<ID[i]<<na[i]<<add[i]<<endl;
  for(k=0;k<=16;)
  {
  for(l=0;l<2;l++)
{
x[l]=ID[i][k];

k++;
}
id=atoi(x);
sum+=id;//关键字定义为十八位身份证号码每两位加在一起的和 
cout<<id<<" "<<sum<<endl;
s[i]=sum;
}
cout<<(sum%47)<<endl;
  InsertHash(H,j,sum,ID[i],na[i],add[i],p); 
 }
 for(i=0;i<n;i++)
cout<<s[i]<<" ";
 datafile.close();
return OK;
}//CreateHash

Status SearchHash(HashTable H,string ID)
{
//查找并显示给定身份信息的记录
int i,j,k,l,key;
char x[2];
int id,sum=0;
Hash h;
for(k=0;k<=16;)
  {
  for(l=0;l<2;l++)
{
x[l]=ID[k];

k++;
}
id=atoi(x);
sum+=id;

cout<<sum; 
key=sum%47;
cout<<endl<<key<<endl;
for(i=0;i<MAXSIZE;i++)
{
if(key==H[i].key)
{
cout<<" "<<i<<endl;
if(ID==H[i].ID)
{
cout<<H[i].ID<<""<<H[i].name<<" "<<H[i].address<<endl;
cout<<1<<endl;
}
else
{
h=&H[i];
cout<<2<<endl;
while(ID!=h->ID)
{
h=h->next;
cout<<3;
}
cout<<h->ID<<" "<<h->name<<" "<<h->address<<endl;
}
break;
}
 } 

}

Status PrintHash(HashTable H,int n,int m){
//输出哈希表
int i;
float a=0;
cout<<"哈希表地址:     ";
for(i=0;i<m;i++)
cout<<setw(6)<<i;//设置域宽为6个字符
cout<<endl<<"哈希表关键字为:       ";
for(i=0;i<m;i++){
if(H[i].key==NULLKEY||H[i].key==DELKEY)
cout<<setw(6);
else 
cout<<setw(6)<<H[i].key;
}
cout<<endl<<"搜索次数:            ";
for(i=0;i<m;i++)
{
if(H[i].key==NULLKEY||H[i].key==DELKEY)
cout<<setw(6);
else 
cout<<setw(6)<<H[i].count;
 } 
 cout<<endl;
 for(i=0;i<m;i++){
  if(H[i].key!=NULLKEY||H[i].key!=DELKEY)
  a=a+H[i].count;
 }
 a=a/n;
 cout<<"平均搜索长度为:"<<a<<endl; 
} //PrintHash

int main()
{
HashTable H;
cout<<"******哈希表演示*****"<<endl; 
int n=47,m=13,p=47;

//int x[]={19,1,23,14,55,68,11,82,36};//示例数据用于测试 
FileCreateHash(H,n,m,p);
cout<<endl;
cout<<"请输入要查找的身份证号码:"<<endl;
string ID;
cin>>ID;
SearchHash(H,ID);
//PrintHash(H,n,m);
return OK;
}

2 个解决方案

#1


崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处, 看不懂时双击下一行,直到能看懂为止

#2


把InsertHash函数内的chain_adress = (Hash)malloc(sizeof(HASH));改成chain_adress = new HASH;试试
malloc只是分配堆内存(不会调用string的构造函数), 而new是分配且内存且在此创建一个对象(会调用构造函数)。

#1


崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处, 看不懂时双击下一行,直到能看懂为止

#2


把InsertHash函数内的chain_adress = (Hash)malloc(sizeof(HASH));改成chain_adress = new HASH;试试
malloc只是分配堆内存(不会调用string的构造函数), 而new是分配且内存且在此创建一个对象(会调用构造函数)。