debugging error - exceptions

i have debugging error:
"First-chance exception at 0x7694c41f in oop_ex2.exe: Microsoft C++ exception: char at memory location 0x002ef4d4.."
i have inner class - tenant class in building class
and it crashes just before the validChars method ends
i check the exceptions- it seems fine, there are try and some catch blocks...

main.cpp (i copied only the relevant code)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "Building.h"
#include <iostream>
using namespace std;
#define NAME 10
int main()
{
	int option;
	Building building;//creating building object
	do
	{
	cout<<"Choose one of the following option:"<<endl<<"1 - tenant insertion"<<endl<<"2 - tenant removal"<<endl
		<<"3 - changing tenant's first and last name"<<endl<<"4 - printing all the tenants"<<endl;
	cin >> option;
	switch (option)
	{
	case 1:
		{
			int id, phoneNum, apartmentNum, level;
			char name[NAME], lastName[NAME];
			cout<<"insert the tenant's details you want to add according the following order:(ID number, first name, last name, phone number, apartment number, level)"<<endl;
			cin>>id>>name>>lastName>>phoneNum>>apartmentNum>>level;//getting the details
			try//in order to check whether the tenant insertion succeeded
			{
				building.addTenant(id,name,lastName,phoneNum,apartmentNum,level);
			}
			catch(char* msg)//catches all the messages
			{
				cout<<"ERROR:"<<msg;
			}
			catch(int num)//used while the allocating memory failed
			{
				cout<<"ERROR:allocating memory was failed!!";
			}
			catch(...)//catches all the unknown exceptions
			{
				cout<<"An unknown error occurred!";
			}
		}
		break;

building.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#pragma once
#include <iostream>
#include <stddef.h>
#include <string>
class Building
{
	class Tenant//inner class 
	{
		int _id;
		char* _name;
		char* _lastName;
		int _phoneNumber;
		int _level;
		Tenant* _next;
		void validChars(const char* word) const;//assitant method - check the validty of the name/last names' chars, 
	public:
		int _apartmentNumber;//public - to enable the building method use that, the tenants pointers (next) were placed according the apartment num
		void setID(const int id);
		void setName(const char* name);
		void setLastName(const char* lastName);
		void setPhoneNum(const int phoneNum);
		void setApartmentNum(const int apartmentNum);
		void setLevel(const int level);
		void setNext(Tenant* next);
		Tenant(const int,const char*,const char*,const int,const int,const int,Tenant*);//constructor
		const int getID() const
		{
			return _id;
		}
		char* getName() const
		{
			return _name;
		}
		char* getLastName() const
		{
			return _lastName;
		}
		const int getPhoneNum() const
		{
			return _phoneNumber;
		}
		const int getApartmentNum() const
		{
			return _apartmentNumber;
		}
		const int getLevel() const
		{
			return _level;
		}
		Tenant* getNext() const
		{
			return _next;
		}
		Tenant(const Tenant&);//copy constructor
		void print() const;
		~Tenant()//deleting the allocated strings
		{
			if (_name!=NULL)
				delete[] _name;
			if (_lastName!=NULL)
				delete[] _lastName;
		}
	};
	Tenant* _head;//pointer to the first tenant,
	int _size;//num of tenants
public:
	static char* changeName;//the changing method got ID num parameter only, and by static vars the method/main can use the vars
	static char* changeLastName;
	Building();
	void addTenant(int,char*,char*,int,int,int);//connects the tenants one to another
private:
	Building::Tenant* getTenant(int) const;
	void delTenant(Tenant*);
public:
	void removeTenant(int);
	void setTenantName(int);
	void setTenantLastName(int);
	void printAll() const;
	~Building();
};

building.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "Building.h"
#include <iostream>
using namespace std;
void Building::Tenant::setID(const int id)
{
	if ((id>=1000000)&&(id<=999999999))
		_id=id;
	else
		throw "incorrect id";
}//check the id validty and set it
void Building::Tenant::validChars(const char* word) const
{
	if (word==NULL)
		throw "incorrect chars";
	int lenWord = strlen(word);
	for(int i=0;i<lenWord;i++)
	{
		if ((word[i]<'65')||(word[i]>'122'))
			throw "incorrect chars";
		word++;
	}
}//check the chars validity
void Building::Tenant::setName(const char* name)
{
	Tenant::validChars(name);//check the chars validty
	if (_name!=NULL)
		delete[] _name;
	_name = new char[strlen(name)+1];
	if (_name!=NULL)
		strcpy(_name,name);
	else
		throw -1;//the allocating failed
}
void Building::Tenant::setLastName(const char* lastName)
{
	Tenant::validChars(lastName);//check the chars validty
	if (_lastName!=NULL)
		delete[] _lastName;
	_lastName = new char[strlen(lastName)+1];
	if (_lastName!=NULL)
		strcpy(_lastName,lastName);
	else
		throw -1;
}
void Building::Tenant::setPhoneNum(const int phoneNum)
{
	if ((phoneNum>=0501000000)&&(phoneNum <= 0570000000))
		_phoneNumber = phoneNum;
	else
		throw "incorrect phone number";
}
void Building::Tenant::setApartmentNum(const int apartmentNum)
{
	if (apartmentNum>0)
		_apartmentNumber=apartmentNum;
	else
		throw "incorrect apartment number";
}
void Building::Tenant::setLevel(const int level)
{
	if (level>0)
		_level=level;
	else
		throw "incorrect level";
}
void Building::Tenant::setNext(Tenant* next)
{
	_next=next;
}
Building::Tenant::Tenant(const int id=0,const char* name=NULL,const char* lastName=NULL,const int phoneNum=0,const int apartmentNum=0,const int level=0,Tenant* next=NULL)
{
	setID(id);
	setName(name);
	setLastName(lastName);
	setPhoneNum(phoneNum);
	setApartmentNum(apartmentNum);
	setLevel(level);
	_next = next;
}
Building::Tenant::Tenant(const Tenant& tenant)
{
	setID(tenant.getID());
	setName(tenant.getName());
	setLastName(tenant.getLastName());
	setPhoneNum(tenant.getPhoneNum());
	setApartmentNum(tenant.getApartmentNum());
	setLevel(tenant.getLevel());
	_next = tenant._next;
}
void Building::Tenant::print() const
{
	cout<<"Tenant ID:"<<getID()<<", name:"<<getName()<<", last name:"<<getLastName()<<", phone number:"<<getPhoneNum()<<", apartment number:"<<getApartmentNum()<<", level:"<<getLevel()<<endl;
}
char* Building::changeName=NULL;
char* Building::changeLastName=NULL;
Building::Building():_size(0)
{
	char* name = new char[strlen("Moshe")+1];
	strcpy(name,"Moshe");
	char* lastName = new char[strlen("Mash")+1];
	strcpy(lastName,"Mash");
	const int id=11111111,phoneNum=0505000000,apartmentNum=1,level=1;
	_head = new Building::Tenant(id,name,lastName,phoneNum,apartmentNum,level);
	_size++;
}
void Building::addTenant(int id=0,char* name=NULL,char* lastName=NULL,int phoneNum=0,int apartmentNum=0,int level=0)
{
	Building::Tenant* p_next;//looking for the right place to connect - add the tenant (placed according the apartment num)
	for(p_next=_head;p_next==NULL;p_next++)//checking identical apartment nums
	{
		if (apartmentNum==(p_next->_apartmentNumber))
			throw "incorrect, there is already such an apartment number";
	}
	 Building::Tenant* tenant=new Building::Tenant(id,name,lastName,phoneNum,apartmentNum,level,NULL);
	if (tenant!=NULL)//checking the allocating
	{
		 int i=0;
	for(p_next=_head;i<=_size; p_next++,i++)
	{
		if ((apartmentNum < (p_next->_apartmentNumber))||(p_next==NULL))
		{
			Tenant* old=p_next;//connecting the previous to the current and the current to the next
			p_next--;
			p_next->setNext(tenant);
			tenant->setNext(old);
			break;
		}
	}
	}
	else
		throw -1;

}
Building::Tenant* Building::getTenant(int id) const
{
	Tenant* p_next;
	for(p_next=_head;p_next==NULL;p_next++)
	{
		if (p_next->getID() == id)
			return p_next;
	}
	throw "there is no tenant with that ID number";
}
You're incrementing your pointer named word and incrementing i at the same time. Every time you increment the pointer it moves over one character, and then you use the subscript operator which is relative to where your pointer now points. Eventually you'll have an out-of-bounds access to something else. You don't want to do word++
Also, adding to yulingo's observation: word[i]<'65' - single quotes are for single char literals, double quotes for strings and char numeric values go without any quotes.

Building constructor:
_head = new Building::Tenant(id,name,lastName,phoneNum,apartmentNum,level);

AddTenant:
1
2
3
4
5
for(p_next=_head;p_next==NULL;p_next++) // run only for null p_next
{
	if (apartmentNum==(p_next->_apartmentNumber)) // dereference p_next which must be null
		throw "incorrect, there is already such an apartment number";
}


What is the idea behind using ++ with p_next? p_next is not pointing to an array element, so it is not safe to increment it because you have no idea what's at p_next + 1 memory location.
Last edited on
Topic archived. No new replies allowed.