这是我要为学校作业解决的问题。我创建了一个包含节点(即包含字符“item”和节点指针“next”的结构)和节点指针头的单个链表类。根据作业的规定,我需要递归地对链表执行多个操作。我已经设法让所有这些工作正常。
但是,作为作业的下一步,我被要求:“编写一个测试程序以确定最长可能的链表是多少。(您将测试堆大小)。您可以这样做很容易,因为附加函数被定义为如果成功则返回 true,否则返回 false。”
在类里面,有人提到我们应该使用类似
的东西try{ //Allocate a new node
// Throw an exception if it fails
}
catch(...){
// Do something with the caught exception
}
对于我来说,我无法让它工作!我收到以下错误:
Assignment.exe 中 0x7765DED4 (ntdll.dll) 处的未处理异常:0xC00000FD:堆栈溢出(参数: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++ - 试图在递归函数 : Unhandled exception/Stack overflow 中捕获失败的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32686574/