我有一个特定的Exception类,我想从类方法中抛出并从main()函数中调用它的调用代码。
然而,当我运行它时,我收到以下错误:
Unhandled exception at 0x775915ee in OpenHashTable.exe: 0xC0000005: Access violation.
好像没有被处理。我不明白为什么会这样。这是涉及的代码:
main() {
......
case 'i':
{
cout << "Enter the positive integer you wish to insert: ";
//Input Validation.
if (!(cin >> number))
{
cout << "Please enter a valid positive integer...\n\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //Taken from http://stackoverflow.com/questions/2075898/good-input-validation-loop-using-cin-c
break;
}
try
{
hashTable.add(abs(number)); //Add positive only integer
}
catch (FullTableException& fte)
{
cout << "HashTable is full!" << endl;
break;
}
catch (DuplicateElementException& dee) //NOT BEING CAUGHT?
{
cout << "HashTable already contains that element." << endl;
break;
}
cout << abs(number) << " added!\n\n";
break;
}
.......
}
这是在HashTable :: add()方法中引发的异常
//Adds an element into the appropriate index
bool OpenHashTable::add(int toAdd) throw(FullTableException, DuplicateElementException)
{
int index = hash(toAdd);
//Check for duplicate
if (search(toAdd))
throw DuplicateElementException(); //NOT ACTUALLY THROWING??
if (arr[index] != 0) //If element is occupied //GET AN ACCESS VIOLATION HERE
{
int j = 0;
//Linear Probing...
for ( unsigned int i = index + 1; j < 100; i = ((i+1) % 100) )
{
if (arr[i] != 0 && arr[i] != -1) //If element is occupied
{
j++; //Keep count of how many tries, for full array
continue;
}
else
{
arr[i] = toAdd; //Add to array
size++; //Increment size
break;
}
}
if (j == 100) //We've checked all possible elements
throw FullTableException(); //No spaces
}
else
{
arr[index] = toAdd; //Add to array straight away
size++; //Increment size
}
return true; //Successfully added
}
编辑:search()方法:
bool OpenHashTable::search(int toSearch)
{
int index = hash(toSearch);
if (arr[index] == toSearch)
return true; //Found at index
else
{
int j = 0;
//Linear search for value
for ( unsigned int i = index + 1; j < 100; i = ((i+1) % 100) )
{
if (arr[i] == toSearch)
return true; //found
else if (arr[i] == 0)
return false; //Not in HashTable
else
continue; //Probe next element
}
if (j == 100)
return false; //Not in HashTable
}
return true;
}
编辑:_ 尝试... _except()调用堆栈:
ntdll.dll!775915ee()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!775915ee()
ntdll.dll!7761852f()
ntdll.dll!776372ec()
ntdll.dll!7760063e()
ntdll.dll!775fabf9()
ntdll.dll!77580143()
KernelBase.dll!75c5b9bc()
KernelBase.dll!75c5b9bc()
KernelBase.dll!75c5b9bc()
msvcr100d.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 157 C++
OpenHashTable.exe!OpenHashTable::add(int toAdd) Line 100 //THIS IS "throw DuplicateElementException()"
OpenHashTable.exe!main() Line 267 //THIS IS "hashTable.add(abs(number));"
编辑:DuplicateElementException:
//Just an empty class
class DuplicateElementException : public exception
{
private:
public:
DuplicateElementException(); //Constructor
~DuplicateElementException(); //Destructor
};
//empty constructor and destructor definitions...
非常感谢任何帮助。
由于
Calum
答案 0 :(得分:5)
抛出的异常是SEH异常“访问冲突”,这意味着您从无效地址读取或写入。这可能是search
或hash
中的错误。并且你的程序没有到达你抛出DuplicateElementException
的行。
此外,不推荐使用异常规范(函数原型之后的抛出),因此不要使用它们。
答案 1 :(得分:4)
抛出的访问冲突异常是一个SEH异常,不会被C ++ catch
块捕获。你最有可能写出超出某些数组的范围,这会引发异常。
要调试此问题,请围绕main
块中__try
内的代码中的所有内容,并在随附的__except
块中放置断点。有关如何执行此操作的详细信息,请参阅MSDN docs。你几乎可以逐字使用那里的代码。在调试模式下运行程序,当命中断点时,检查调用堆栈以找出抛出SEH异常的行。
此外,除非你有一个非常令人信服的理由使用C数组,否则你应该使用std::array
(如果数组的大小是固定的)或哈希表的std::vector
。在Visual Studio operator[]
上,这两个都将在调试模式下执行范围检查,并在索引超出范围时抛出std::out_of_range
异常。您还可以使用at()
成员函数同时使它们在发布模式下执行边界检查。在任何一种情况下,调试都要比搞乱SEH的东西容易得多。
修改强>
使用__try
- __except
调试问题需要进行一些代码重构,因为您无法使用__try
包含包含C ++对象销毁的代码。
要解决此问题,请创建一个名为int mainHelper()
的函数,并将main
内的所有代码移动到此函数中。现在,您的代码应如下所示:
int mainHelper()
{
/* All your code from main goes here */
}
int main()
{
__try {
return mainHelper();
} __except( filter(GetExceptionCode(), GetExceptionInformation()) ) {
puts("in except");
}
}
答案 2 :(得分:0)
似乎索引超出了数组arr的范围。它使您的进程从未分配给它的内存中读取并崩溃。这不是C ++异常,而是操作系统告诉您的程序。
答案 3 :(得分:-2)
使用try - &gt;可以很容易地在Visual Studio中捕获任何类型的异常(除以零,访问冲突等)。捕获(...)块。一个小项目调整就足够了。只需在项目设置中启用/ EHa选项。请参阅项目属性 - &gt; C / C ++ - &gt;代码生成 - &gt;将“启用C ++例外”修改为“是和SEH例外”。就是这样!
详情请见: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx