首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++:抓块抓不到吗?

C++:抓块抓不到吗?
EN

Stack Overflow用户
提问于 2011-10-23 16:56:14
回答 4查看 1.8K关注 0票数 0

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

然而,当我运行它时,我会得到以下错误:Unhandled exception at 0x775915ee in OpenHashTable.exe: 0xC0000005: Access violation.,好像它没有被处理一样。我不明白为什么这是触碰。下面是所涉及的代码:

代码语言:javascript
运行
复制
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()方法

代码语言:javascript
运行
复制
    //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()方法:

代码语言:javascript
运行
复制
    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;
}

编辑:_try..._except()调用堆栈:

代码语言:javascript
运行
复制
    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:

代码语言:javascript
运行
复制
//Just an empty class
class DuplicateElementException : public exception
{
private:
public:
    DuplicateElementException();   //Constructor
    ~DuplicateElementException();   //Destructor
};
//empty constructor and destructor definitions...

任何帮助都是非常感谢的。

谢谢

卡勒姆

EN

回答 4

Stack Overflow用户

发布于 2011-10-23 17:00:58

引发的异常是SEH异常“访问冲突”,这意味着您从无效地址读取或写入。这可能是searchhash中的一个bug。而且你的程序没有到达抛出DuplicateElementException的那一行。

此外,异常规范(函数原型之后的抛出)也是不推荐的,所以不要使用它们。

票数 5
EN

Stack Overflow用户

发布于 2011-10-23 17:09:01

引发的访问冲突异常是SEH异常,不会被C++ catch块捕获。您很可能会超出某些数组的范围,这会导致抛出异常。

要调试这个问题,请将main代码中的所有内容都封装在__try块中,并将断点放置在伴随的__except块中。有关如何做到这一点的详细信息,可以在MSDN文档中找到。您几乎可以逐字使用其中的代码。在调试模式下运行您的程序,当命中断点时,检查调用堆栈,以确定SEH异常抛出在哪一行。

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

编辑:

使用__try - __except调试问题需要一点代码重构,因为不能用__try包围包含C++对象破坏的代码。

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

代码语言:javascript
运行
复制
int mainHelper()
{
  /* All your code from main goes here */
}

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

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

  }
}
票数 4
EN

Stack Overflow用户

发布于 2011-10-23 17:02:01

似乎索引超出了数组arr的范围。它使进程从未分配给它的内存中读取并崩溃。这不是一个C++异常,而是操作系统告诉您的程序。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7867619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档