C++ C++;:抓块不抓?

C++ C++;:抓块不抓?,c++,oop,exception,exception-handling,try-catch,C++,Oop,Exception,Exception Handling,Try Catch,我有一个特定的异常类,我想从类方法中抛出,并从main()函数中调用它的代码中捕获 但是,当我运行它时,会出现以下错误: OpenHashTable.exe中0x775915ee处未处理的异常:0xC0000005:访问冲突。就好像它没有被处理一样。我不明白为什么这是幸福的。以下是相关代码: main() { ...... case 'i': { cout << "Enter the positive in

我有一个特定的异常类,我想从类方法中抛出,并从main()函数中调用它的代码中捕获

但是,当我运行它时,会出现以下错误:
OpenHashTable.exe中0x775915ee处未处理的异常:0xC0000005:访问冲突。
就好像它没有被处理一样。我不明白为什么这是幸福的。以下是相关代码:

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;
        }
     .......
}
编辑:DuplicateElementException:

//Just an empty class
class DuplicateElementException : public exception
{
private:
public:
    DuplicateElementException();   //Constructor
    ~DuplicateElementException();   //Destructor
};
//empty constructor and destructor definitions...
非常感谢您的帮助

谢谢


Calum

引发的异常是SEH异常“访问冲突”,这意味着您从无效地址读取或写入。这可能是
搜索
散列
中的错误。并且您的程序没有到达抛出
DuplicateElementException
的行


此外,异常规范(函数原型后的抛出)已被弃用,因此不要使用它们。

似乎索引超出了数组arr的范围。它会使进程从未分配给它的内存中读取并崩溃。这不是C++异常,而是OS告诉程序的东西。< /p> < p>抛出的访问违例异常是SEH异常,不会被C++ <代码> catch < /C>块阻止。您很可能正在写入超出某个数组边界的内容,这导致抛出异常

要调试此问题,请将
main
中的所有代码都包围在
\u try
块中,并在附带的
\u块中放置断点,但
块除外。有关如何执行此操作的详细信息,请参见。您几乎可以一字不差地使用其中的代码。在调试模式下运行程序,当遇到断点时,检查调用堆栈以确定SEH异常抛出的行

另外,除非您有非常令人信服的理由使用C数组,否则您应该使用
std::array
(如果数组的大小是固定的)或
std::vector
作为哈希表。在Visual Studio上,运算符[]
将在调试模式下执行范围检查,并在索引超出范围时抛出
std::out_of_range
异常。您还可以将
at()
成员函数与这两个函数一起使用,让它们也在发布模式下执行边界检查。无论哪种情况,调试都比处理SEH的东西容易得多

编辑:
需要使用代码重构来调试问题,使用代码< >代码> <代码> ->代码>除<代码>之外,因为不能用“代码> > < < />代码>包围C++对象销毁代码。

要解决此问题,请创建一个名为
int mainheloper()
的函数,并将
main
中的所有代码移动到此函数。现在,您的代码应该如下所示:

int mainHelper()
{
  /* All your code from main goes here */
}

int main()
{
  __try {
    return mainHelper();

  } __except( filter(GetExceptionCode(), GetExceptionInformation()) ) {
    puts("in except");

  }
}

在VisualStudio中,使用try->catch(…)块可以很容易地捕获任何类型的异常(除零、访问冲突等)。一个小的项目调整就足够了。只需在项目设置中启用/EHa选项。请参阅<强>项目属性> C/C++ >代码生成> >将启用C++异常修改为“具有SEH异常的是”<强>。就这样

详情如下:

您的搜索方法是什么?另外,您不应该按表大小修改哈希值吗。不知道你的意思。散列函数只是
值%100
(100是表大小)请发布
DuplicateElementException
当用户输入非数字(如f)时,代码中有一个错误当密钥不在表中时,您的搜索是一个无限循环。大多数编译器不会以符合标准的方式实现异常规范,但它们是否已被正式弃用?感谢您的更新。现在是时候摆脱这些了:)search()方法添加,看不到错误。在调试中,它似乎在
if(search(toAdd))
中执行了步骤,但在
throw
语句中失败。啊,我不知道有人反对,谢谢。@CalumMurray:根据我们掌握的信息,这听起来是不可能的。所以,要么你误解了你所看到的,给了我们错误的信息,要么某些东西在低层次上真的被破坏了。我只能建议您调试生成的程序集以确定真正的问题。这就是我应该做的。顺便说一句,当用/EHa编译时,SEH可以用
catch(…)
捕获。@ybungalobill它可以,但我记得在某个地方读到,设置该选项不是很理想。不幸的是,我不记得所说的理由了。谢谢。除了(expression)
语句之外,我不确定在
\u语句中放入什么作为表达式。我在一个大小为100的数组中只使用了3的索引,所以我看不出在哪里会生成数组越界错误。@CalumMurray复制粘贴
filter()
函数,完全如上图所示
main
并将
filter(GetExceptionCode(),GetExceptionInformation())
放在
\uu except
表达式中。您不必使用该示例中所示的内部
\uu try
-
\uu finally
构造。其他一切都可以保持不变。在行
Put(“in-except”)上放置断点无法使用需要对象展开的uu-try-in函数。我不知道如何访问越界。我用索引3测试它,数组大小为100。@CalumMurray您有两行代码:int index=hash(toSearch);如果(arr[index]==toSearch),您应该在访问arr[index]之前检查散列(toSearch)返回的内容。您如何声明大小为100的arr?(我在你粘贴的代码中看不到)你提供了一个可能很危险的解决方案,但没有提到它的缺点。我不知道缺点。如果你知道,为什么不告诉我?对我来说,这个解决方案非常完美,m
    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));"
//Just an empty class
class DuplicateElementException : public exception
{
private:
public:
    DuplicateElementException();   //Constructor
    ~DuplicateElementException();   //Destructor
};
//empty constructor and destructor definitions...
int mainHelper()
{
  /* All your code from main goes here */
}

int main()
{
  __try {
    return mainHelper();

  } __except( filter(GetExceptionCode(), GetExceptionInformation()) ) {
    puts("in except");

  }
}