试图在递归函数内部捕获失败的分配:未处理的异常/堆栈溢出
Trying to catch a failed allocation inside of a recursive function: Unhandled exception/Stack overflow
这是我想解决的一个学校作业问题。我创建了一个单独的链表类,其中包含一个Node(即。(包含字符"item"和节点指针"next")和节点指针头的结构体。正如赋值所指定的,我需要在链表上递归地实现几个操作。我已经设法使这一切工作良好。
然而,作为作业的下一步,我被要求:"写一个测试程序来确定最长的可能链表是什么。(您将测试堆大小)。您可以很容易地做到这一点,因为append函数被定义为如果成功返回true,否则返回false。"
在课堂上,有人提到我们应该使用
之类的东西。try{ //Allocate a new node
// Throw an exception if it fails
}
catch(...){
// Do something with the caught exception
}
我的生命,我不能让这个工作!我得到以下错误:
Unhandled exception at 0x7765DED4 (ntdll.dll) in Assignment.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00352FFC).
这是我第一次处理异常,所以也许我遗漏了什么,但我已经在谷歌和我的教科书收集中拖网了几个小时,我正式被困住了。
下面是问题代码:
// RECURSIVELY appends an element to the end of the list
bool LinkedList::append(char newChar){
if (head == nullptr){ // Adds a node to empty list
head = new Node{ newChar, nullptr };
return true;
}
return appendHelper(newChar, head); // Call the recursive helper function
}
// Helper function for append
bool LinkedList::appendHelper(char newChar, Node* currentNode){
if (currentNode->next == nullptr){ // Adds a node to the end of a list
// HERE'S WHERE THE TROUBLE BEGINS:
try{
currentNode->next = new Node{ newChar, nullptr }; // From what I've read, this should throw std::bad_alloc if it fails?
}
catch(...){ // The "..." should catch ANY exception, right?
return false; // Return false, so that I'll know allocation failed
}
return true; // Mustn't have encountered an exception; return true.
}
return appendHelper(newChar, currentNode->next);
}
我相当有信心,我的代码,除了异常处理,工作。Ie。使用:
添加节点currentNode->next = new Node{ newChar, nullptr };
似乎可以正常工作。我们在课堂上的讨论给我留下的印象是,当分配失败时,我应该能够捕获异常,返回false,然后继续我的程序/实验的其余部分…
知道我在哪里做错了,或者我怎么解决这个问题吗?我开始认为我应该迭代一个计数器,并在每次调用append()
函数时将其打印到屏幕上,然后在它崩溃时记录这个数字……但是这看起来不是很优雅,我也不觉得这是期望的。
必须区分两种异常:硬件异常和软件异常。c++异常可以被视为软件异常,因此使用c++ try/catch语句只能捕获软件异常。软件异常的一个例子是当程序检测到为某些过程指定了无效参数时。
硬件异常要严重得多,是由CPU自己抛出的。硬件异常的例子有:除零,试图访问无效的内存地址,堆栈溢出和其他。许多这些硬件异常由操作系统本身处理(调试器也处理其中一些异常),强烈建议不要在程序中捕获这些异常。这样做可能会阻止较低级系统正确地清理留下的混乱。
回到你遇到的堆栈溢出问题,当这个硬件异常发生时,堆栈指针超过了堆栈边界。换句话说,您的程序超出了堆栈(这是过度简化,因为进程中的每个线程都获得一定数量的堆栈空间,所以可能只有线程耗尽了堆栈)。即使您要处理这个异常,您想要做什么?你的栈外,所以你的选择是非常有限的(例如,甚至定义一个局部变量,或调用一个函数可能会导致另一个异常)。
这就是为什么程序不应该处理这样的异常——在应用程序级别,你只是没有足够的智慧来正确恢复,而操作系统能够清理你的应用程序产生的混乱。
也就是说,Windows允许你捕获这样的异常…结构化异常处理可用于捕获Windows上的硬件和软件异常。但是,如果你是一个聪明的程序员,你可能不会这样做。
结构化异常处理关于硬件异常的更多信息
- 在c++中实现LinkedList时,应出现未处理的错误
- 如何修复链表类实现的未处理异常0xDDDDDDDD
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 在C++程序中使用的迭代器中未处理的异常
- 在 ******.exe 中0x00000000772CA267 (ntdll.dll) 处未处理的异常:0xC0000
- 未处理的异常与 cudaMemcpy2D
- 处理未处理的异常更改C++
- for 循环中未处理的异常
- VisualC++ 2010 有没有办法找出有关未处理异常错误的更多详细信息
- 为什么此代码导致未处理的异常失败
- 瓦尔格林德:注意到但未处理的国际奥克特尔;是否有必要处理以及如何找到?
- 在OpenCV_core310.dll中使用findContours函数时,OpenCV引发未处理的异常
- 0x0F50DF58:0xC0000005:访问冲突读取位置0x0047CA04时未处理的异常
- 使用 getline 时未处理的异常
- 错误 : 异常 : 引发未处理的异常: 读取访问冲突.0xDDDDDDDD临时温度
- 核心消息传递中未处理的异常.dll在程序关闭期间
- 在 Hello World.exe 中0x0F828F0E (ucrtbased.dll) 处未处理的异常: 0xC00
- 从向量中删除元素时未处理的异常
- 试图在递归函数内部捕获失败的分配:未处理的异常/堆栈溢出
- 分配martix元素时出现未处理的异常