首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

Unhandled exception 有关问题

2013-04-02 
Unhandled exception 问题本人用C++编写一个程序,编译没错,运行就出现Unhandled exception 问题了,求各位

Unhandled exception 问题
本人用C++编写一个程序,编译没错,运行就出现Unhandled exception 问题了,求各位帮忙解决一下。代码如下:
头文件:LinkList.h:
#ifndef  __LINKLIST_H__
#define  __LINKLIST_H__
#include"iostream"
#include <stdlib.h>
#include<string>
#include<string.h>

using namespace std;

struct  LinkNode
{
string  name;
double  number;   //工号
double  telenumber;  //电话号码
LinkNode* next;
LinkNode(LinkNode *ptr=NULL){next=ptr;}
LinkNode(string name,double number,double telenumber):name(name),number(number),telenumber(telenumber){}
//LinkNode(string name,double number,double telenumber,LinkNode *next):
//        name(name),number(number),telenumber(telenumber),next(next){}
};

class LinkedList
{
public:
LinkedList(){first=NULL;}
~LinkedList(){Empty();};
void create();
LinkNode* delName(LinkNode *first,string name);  //按姓名删除
LinkNode* delNum(LinkNode* L,double i);        //按工号删除
bool insert(string name,double num,double tele,int i);       //插入
    LinkNode* searchName(/*LinkNode* L,*/string name);                  //按姓名查找
LinkNode* searchNum(double num);                  //按工号查找
LinkNode* searchTele(double tele);      //按电话查找
void Show();        //显示通讯录
LinkNode *first;     //头指针
private:
LinkNode * Locate(int i);
void  Empty();

};

void LinkedList::Empty()
{
LinkNode* q;
while(first!=NULL)
{
q=first->next;
first->next=q->next;
delete q;
}
}

void LinkedList::create()
{
LinkNode *newNode,*current= first;
string name;
double num,tele;
cout<<"请输入工号:"<<endl;
cin>>num;
cout<<"请输入姓名:"<<endl;
cin>>name;
cout<<"请输入电话号码:"<<endl;
cin>>tele;

    while(num>=0)
{
newNode=new LinkNode(name,num,tele);
if(newNode==NULL){cerr<<"存储分配错误!"<<endl;exit(1);}
current->next=newNode;   //问题就出在这里
current=newNode;  
cout<<"请输入工号:"<<endl;
cin>>num;
cout<<"请输入姓名:"<<endl;
cin>>name;
cout<<endl<<"请输入电话号码:"<<endl;
cin>>tele;
}
//current->next=NULL;
}

LinkNode* LinkedList::delName(LinkNode *first,string name)
{
cout<<"请输入删除人姓名: ";
cin>>name;
LinkNode *p=first;
if(p->next->name!=name)
{
p=p->next;
}
    p->next=p->next->next;
delete p;
return p;
}

LinkNode* LinkedList::delNum(LinkNode* L,double i)
{
LinkNode* p=L;
cin>>i;
if(p->number!=i)p=p->next;
delete p;
return p;
}

LinkNode * LinkedList::Locate(int i)
{
if(i<0)return NULL;


LinkNode* current=first;
int k=0;
while(current!=NULL && k<i)
{
current=current->next;
k++;
}
return current;
}

bool   LinkedList::insert(string name,double num,double tele,int i)
{

LinkNode* current=Locate(i);
if(current==NULL)return false ;
LinkNode *newNode=new LinkNode(name,num,tele);
if(newNode==NULL){cerr<<"存储分配错误!"<<endl;}
newNode->next=current->next;
current->next=newNode;
return true;
}

LinkNode* LinkedList::searchName(string name)
{
LinkNode* L=first;
LinkNode *p=L;
if(p->name!=name)p=p->next;
if(p->next=NULL)return false;
cout<<p->number<<p->name<<p->telenumber<<endl;
return p;
}

LinkNode*  LinkedList::searchNum(double num)
{
LinkNode* p=first;
if(p->number!=num)p=p->next;
if(p->next=NULL)return false;
return p;
}

LinkNode* LinkedList::searchTele(double tele)
{
LinkNode* p=first;
if(p->telenumber!=tele)p=p->next;
if(p->next=NULL)return false;
return p;
}

void LinkedList::Show()
{
LinkNode* p=first;
if(first==NULL){cerr<<"错误!"<<endl;exit(1);}
else  while(p!=NULL)
{
cout<<p->name<<p->number<<p->telenumber<<endl;
p=p->next;
}
}

#endif

文件main.cpp:
#include"LinkList.h"
#include<iostream>
using namespace std;

void jingcheng();
void find();
void del();

void main()
{
system("color lf");
system("mode con:cols=78 lines=35");
LinkedList L;
jingcheng();
int ch;
cin>>ch;
//while(ch!=0){
//void xunhan(){
switch(ch)
{
case 1:
{
    L.create();
L.Show();
//break;
}
case 2:
{
double num;
cout<<"请输入工号:"<<endl;
cin>>num;
string name;
cout<<"请输入姓名:"<<endl;
cin>>name;
double tele;
cout<<"请输入电话号码:"<<endl;
cin>>tele;
int i;
cout<<"请输入序号:"<<endl;
cin>>i;
while(num>0)
{
    L.insert(name,num,tele,i);
cout<<"请输入工号:"<<endl;
    cin>>num;
cout<<"请输入姓名:"<<endl;
     cin>>name;
cout<<"请输入电话号码:"<<endl;
    cin>>tele;
cout<<"请输入序号:"<<endl;
    cin>>i;
}
//break;
}
case 3:
{
find();
int hr;
cin>>hr;
switch(hr)
{
case 1:
{
    string name;
    cout<<"请输入姓名:"<<endl;
    cin>>name;
    LinkNode* p;
if(L.first==NULL){cerr<<"未找到!"<<endl;exit(1);}
    else p=L.searchName(name);
cout<<p->number<<p->name<<p->telenumber<<endl;
//break;
}
case 2:
{
double  num;
                cout<<"请输入工号:"<<endl;


                cin>>num;
LinkNode* p;
if(L.first==NULL){cerr<<"未找到!"<<endl;exit(1);}
else p=L.searchNum(num);
cout<<p->number<<p->name<<p->telenumber<<endl;
//break;
}
case 3:
{
double tele;
cout<<"请输入电话号码:"<<endl;
cin>>tele;
LinkNode* p;
if(L.first==NULL){cerr<<"未找到!"<<endl;exit(1);}
else p=L.searchTele(tele);
cout<<p->number<<p->name<<p->telenumber<<endl;
//break;
}
default:
break;
}
}
case 4:
L.Show();
case 5:
{
del();
int co;
cin>>co;
switch(co)
{
case 1:
{


}

}
}
;
}

}
文件jingcheng.cpp:
#include<iostream>
using namespace std;
void jingcheng()
{
    cout<<"**********************欢迎使用员工通讯录系统*********************************"<<endl;
cout<<"*                     1、通讯录建立                                          *"<<endl;
cout<<"*                     2、插入通讯记录                                        *"<<endl;
cout<<"*                     3、查询通讯录                                          *"<<endl;
cout<<"*                     4、显示通讯记录                                        *"<<endl;
cout<<"*                     5、删除通讯记录                                        *"<<endl;
cout<<"*                     0、退出通讯录                                          *"<<endl;
cout<<"**********************欢迎使用员工通讯录系统********************************"<<endl;
cout<<"请选择:0~5"<<endl;
}

文件find.cpp:
#include<iostream>


using namespace std;

void  find()
{
cout<<"******************************************"<<endl;
cout<<"*             请选择查找方式             *"<<endl;
cout<<"*            1、按姓名查找               *"<<endl;
cout<<"*            2、按工号查找               *"<<endl;
cout<<"*            3、按电话查找               *"<<endl;
cout<<"*            0、退出                     *"<<endl;
cout<<"******************************************"<<endl;
cout<<"请选择0~3:                                "<<endl;
}

文件del.cpp:
#include<iostream>
using namespace std;

void del()
{
cout<<"******************************************"<<endl;
cout<<"*             请选择删除方式             *"<<endl;
cout<<"*            1、按姓名删除               *"<<endl;
cout<<"*            2、按工号删除               *"<<endl;
//cout<<"*            3、按电话查找               *"<<endl;
cout<<"*            0、退出                     *"<<endl;
cout<<"******************************************"<<endl;
cout<<"请选择0~2:                                "<<endl;
}




exception
[解决办法]
肯定是内存访问异常。
[解决办法]
if(p->next=NULL)return false;  

这里改为p->next==NULL 这里有几处,自己改正吧。
[解决办法]
current可能为NULL
[解决办法]

引用:
引用:if(p->next=NULL)return false;  

这里改为p->next==NULL 这里有几处,自己改正吧。这里不是重点,改了也一样出现Unhandled


LinkNode(LinkNode *ptr=NULL){next=ptr;} 这里有点问题,改为 == 试试。



自己单步跟踪下吧。
[解决办法]

引用:
本人用C++编写一个程序,编译没错,运行就出现Unhandled exception 问题了,求各位帮忙解决一下。代码如下:
头文件:LinkList.h:
#ifndef  __LINKLIST_H__
#define  __LINKLIST_H__
#include"iostream"
#include <stdlib.h>
#include<string……

空指针异常。代码做了一些修改,注释已经说明了。

// 头文件LinkList.h
#ifndef  __LINKLIST_H__
#define  __LINKLIST_H__
#include"iostream"
#include <stdlib.h>
#include<string>
#include<string.h>

using namespace std;

struct LinkNode
{
string name;
// 工号和电话号码用浮点数保存不合理,换成int
// 后面所有的double我都会换成int,并且不再用注释说明
//double number;   //工号
//double telenumber;  //电话号码
int number;   //工号
int telenumber;  //电话号码
LinkNode* next;

// 添加成员变量的初始化,当然,这并非绝对必要,只是我看不惯这里的警告
LinkNode(LinkNode *ptr = NULL)
:number(0), telenumber(0)
{
next = ptr;
}

// 真是危险的写法,尽量不要重名,虽然这种情况编译器能正确分辨
// 添加next指针的初始化
//LinkNode(string name, double number, double telenumber) :
//name(name), number(number), telenumber(telenumber)
LinkNode(string name, int num, int tel) :
name(name), number(num), telenumber(tel), next(NULL)
{
}

//LinkNode(string name,double number,double telenumber,LinkNode *next):
//name(name),number(number),telenumber(telenumber),next(next){}
};

class LinkedList
{
public:
LinkedList()
{
// 为了方便处理,这里创建一个头结点
// 另外,错误的根源也在此
//first = NULL;
first = new LinkNode();
}

// 这里最后的分号有些多余,不过不影响什么,每个人都会无意中碰到这种情况
~LinkedList()
{
Empty();
}
;

void create();
LinkNode* delName(LinkNode *first, string name);  //按姓名删除
LinkNode* delNum(LinkNode* L, int i);        //按工号删除

// 这个是演示函数
void delTel(int tel);// 按电话号码删除

bool insert(string name, int num, int tel, int i);       //插入
LinkNode* searchName(/*LinkNode* L,*/string name);                  //按姓名查找
LinkNode* searchNum(int num);                  //按工号查找
LinkNode* searchTele(int tele);      //按电话查找
void Show();        //显示通讯录
LinkNode *first;     //头指针
private:
LinkNode * Locate(int i);
void Empty();
};

void LinkedList::Empty()
{
LinkNode* q;
while (first != NULL)
{
q = first->next;
first->next = q->next;
delete q;
}
// 这里也同时会释放掉头结点分配的内存
}

void LinkedList::create()
{
LinkNode *newNode, *current = first;
string name;
int num, tele;
cout << "请输入工号:" << endl;
cin >> num;
cout << "请输入姓名:" << endl;


cin >> name;
cout << "请输入电话号码:" << endl;
cin >> tele;

// 这里存在部分代码重复,可以换成无限循环 + 条件break的方式解决
while (num >= 0)
{
newNode = new LinkNode(name, num, tele);
if (newNode == NULL)
{
cerr << "存储分配错误!" << endl;
exit(1);
}

// 如果不使用头结点,那么第一次运行的时候,current为NULL,这里肯定内存访问错误
// 添加一个头结点之后,可以保证current不会为空
// 使用头结点可以减少特殊情况,如空链表插入等,其好处可以参考各种数据结构方面的书籍
current->next = newNode;   //问题就出在这里
current = newNode;

cout << "请输入工号:" << endl;
cin >> num;
cout << "请输入姓名:" << endl;
cin >> name;
cout << endl << "请输入电话号码:" << endl;
cin >> tele;
}
//current->next=NULL;
}

// 你这两个del函数的逻辑我实在是不能理解,为什么还会有一个LinkNode*参数?
// 如果是想从整个链表中删除符合某项条件的节点的话,我给你写个示例delTel
void LinkedList::delTel(int tel)
{
LinkNode* pre = first;
LinkNode* p = first->next;
// 这里只用了一个临时变量,我觉得这比用两个更方便理解
while (p != NULL && p->telenumber != tel)
{
pre = p;
p = p->next;
}
if (p != NULL)// 找到节点了
{
pre->next = p->next;// 将p指向的节点从链表中移除
delete p;
}
}
LinkNode* LinkedList::delName(LinkNode *first, string name)
{
cout << "请输入删除人姓名: ";
cin >> name;
LinkNode *p = first;
if (p->next->name != name)
{
p = p->next;
}
p->next = p->next->next;
delete p;
return p;
}

LinkNode* LinkedList::delNum(LinkNode* L, int i)
{
LinkNode* p = L;
cin >> i;
if (p->number != i)
p = p->next;
delete p;
return p;
}

// 定位到第i个节点,返回值是这个节点的指针,返回NULL表示不存在第i个节点
LinkNode * LinkedList::Locate(int i)
{
if (i < 0)
return NULL;
// 添加头结点之后,第一个节点的指针就不是first了,而是first->next
//LinkNode* current = first;
LinkNode* current = first->next;
int k = 0;
while (current != NULL && k < i)
{
current = current->next;
k++;
}
return current;
}

// 插入到第i个节点之后
bool LinkedList::insert(string name, int num, int tele, int i)
{
LinkNode* current = Locate(i);
if (current == NULL)
return false;
LinkNode *newNode = new LinkNode(name, num, tele);
if (newNode == NULL)
{
cerr << "存储分配错误!" << endl;
}
// 添加到链表中,很好
newNode->next = current->next;
current->next = newNode;
return true;
}

LinkNode* LinkedList::searchName(string name)
{
#if 0
LinkNode* L = first;
LinkNode* p = L;

// 该函数的实现有问题,最起码得有个循环吧
// 另外,不检查指针是否为NULL,很容易就崩溃了
if (p->name != name)
p = p->next;
// ==写成=了


// if(p->next=NULL)return false;
if (p->next == NULL)
// 函数要返回LinkNode*,这里返回false肯定不对啦
return false;
cout << p->number << p->name << p->telenumber << endl;
#endif

// 修改实现
LinkNode* p = first;
while (p != NULL && p->name != name)
p = p->next;

if (p != NULL)
{
cout << p->number << p->name << p->telenumber << endl;
}
return p;
}

LinkNode* LinkedList::searchNum(int num)
{
LinkNode* p = first;
#if 0
if (p->number != num)
p = p->next;
// ==写成=了
// if (p->next = NULL)
if (p->next == NULL)
return false;
#endif
// 同searchName
while (p != NULL && p->number != num)
p = p->next;
return p;
}

LinkNode* LinkedList::searchTele(int tele)
{
LinkNode* p = first;
#if 0
if (p->telenumber != tele)
p = p->next;
// ==写成=了
// if (p->next = NULL)
if (p->next == NULL)
return false;
#endif
// 同searchNum
while (p != NULL && p->telenumber != tele)
p = p->next;
return p;
}

void LinkedList::Show()
{
// 添加头结点之后,第一个有效的存储节点为first->next
// 并且,判断链表是否为空也改为判断p,而不是first
LinkNode* p = first->next;
if (p == NULL)
//LinkNode* p = first;
//if (first == NULL)
{
cerr << "错误!" << endl;
exit(1);
}
else
{
while (p != NULL)
{
cout << p->name << p->number << p->telenumber << endl;
p = p->next;
}
}
}

#endif

// main.cpp
#include"LinkList.h"
#include<iostream>
using namespace std;

void jingcheng();
void find();
void del();

int main()
{
//system("color lf");
//system("mode con:cols=78 lines=35");

LinkedList L;

// 主程序的逻辑有些问题,你显然是想让操作可以一直进行,但是又不知道该怎么做吧?
// 下面是其中一种比较常见的思路:
//for (bool exit_ = false; !exit_; )
//{
//// 输出操作菜单
//int ch;
//cin >> ch;
//switch (ch)
//{
//case 1: break; // 处理各种命令,注意break
//case 2: break;
//case 3: break;
//case 4: exit_ = true; break; // 处理退出系统的命令
//default: break;
//}
//}

// 下面的代码我就不改了,你可以套用上面的形式自己练习一下^_^

jingcheng();
int ch;
cin >> ch;
//while(ch!=0){
//void xunhan(){
switch (ch)
{
case 1:
{
L.create();
L.Show();
}
// break;
case 2:
{
double num;
cout << "请输入工号:" << endl;
cin >> num;
string name;
cout << "请输入姓名:" << endl;
cin >> name;


double tele;
cout << "请输入电话号码:" << endl;
cin >> tele;
int i;
cout << "请输入序号:" << endl;
cin >> i;
while (num > 0)
{
L.insert(name, num, tele, i);
cout << "请输入工号:" << endl;
cin >> num;
cout << "请输入姓名:" << endl;
cin >> name;
cout << "请输入电话号码:" << endl;
cin >> tele;
cout << "请输入序号:" << endl;
cin >> i;
}
// break;
}
case 3:
{
find();
int hr;
cin >> hr;
switch (hr)
{
case 1:
{
string name;
cout << "请输入姓名:" << endl;
cin >> name;
LinkNode* p;
if (L.first == NULL)
{
cerr << "未找到!" << endl;
exit(1);
}
else
p = L.searchName(name);
cout << p->number << p->name << p->telenumber << endl;
// break;
}
case 2:
{
double num;
cout << "请输入工号:" << endl;
cin >> num;
LinkNode* p;
if (L.first == NULL)
{
cerr << "未找到!" << endl;
exit(1);
}
else
p = L.searchNum(num);
cout << p->number << p->name << p->telenumber << endl;
// break;
}
case 3:
{
double tele;
cout << "请输入电话号码:" << endl;
cin >> tele;
LinkNode* p;
if (L.first == NULL)
{
cerr << "未找到!" << endl;
exit(1);
}
else
p = L.searchTele(tele);
cout << p->number << p->name << p->telenumber << endl;
//break;
}
default:
break;
}
}
case 4:
L.Show();
case 5:
{
del();
int co;
cin >> co;
switch (co)
{
case 1:
{

}

}
}
;
}
return 0;
}


[解决办法]
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。

热点排行