如何在c++中处理双自由崩溃

how to handle double free crash in c++

本文关键字:自由 崩溃 处理 c++      更新时间:2023-10-16

删除双指针将导致程序崩溃等有害影响,程序员应尽量避免这种情况,因为这是不允许的。但有时如果有人这样做,我该如何处理。因为C++中的delete不是except运算符,它不会抛出任何异常。它的文字类型也是无效的。那么我们该如何捕捉这种例外情况呢。以下是的代码片段

class myException: public std::runtime_error
{
public:
myException(std::string const& msg):
std::runtime_error(msg)
{
cout<<"inside class n";
}
};
void main()
{
int* set = new int[100];
cout <<"memory allcated n";
//use set[]
delete [] set;
cout <<"After delete first n";
try{
delete [] set;
throw myException("Error while deleting data n");
}
catch(std::exception &e)
{
cout<<"exception n";
}
catch(...)
{
cout<<"generic catch n";
}
cout <<"After delete second n";

在这种情况下,我试图捕捉异常,但没有成功。请提供您的意见,我们将如何处理此类情况。提前感谢!!!

考虑到后续delete[]上的行为是未定义的,除了编写之外,您什么都做不了

set = nullptr;

紧接在第一个CCD_ 3之后。这利用了删除nullptr是无效的事实。

但实际上,这只是鼓励程序员草率行事。

异常无法捕获分段故障、错误内存访问或总线错误。程序员需要正确管理自己的内存,因为C/C++中没有垃圾收集

但是你用的是C++,不是吗?为什么不利用RAII
以下是您应该努力做到的:

  1. 内存所有权-通过使用std::unique_ptrstd::shared_ptr和家族来明确
  2. 没有对newdelete的显式原始调用。使用make_uniquemake_sharedallocate_shared
  3. 使用像std::vectorstd::array这样的容器,而不是创建动态数组或在堆栈上分别分配数组
  4. 通过valgrind(Memcheck)运行代码,以确保代码中没有与内存相关的问题

如果使用shared_ptr,则可以使用weak_ptr访问底层指针,而无需增加引用计数。在这种情况下,如果基础指针已被删除,则会引发bad_weak_ptr异常。这是我所知道的唯一一种情况,当访问已删除的指针时,会抛出异常供您捕获。

一个代码在提交之前必须经历多个级别的测试迭代,可能使用不同的工具集。

c++中有一个非常重要的概念,称为RAII(资源获取是初始化)。

这个概念概括了这样一种观点,即除非对象完全可用且内部一致,否则任何对象都不可能存在,并且删除对象将释放它所拥有的任何资源。

因此,在分配内存时,我们使用智能指针:

#include <memory>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
using namespace std;
// allocate an array into a smart pointer
auto set = std::make_unique<int[]>(100);
cout <<"memory allocated n";
//use set[]
for (int i = 0 ; i < 100 ; ++i) {
set[i] = i * 2;
}
std::copy(&set[0], &set[100] , std::ostream_iterator<int>(cout, ", "));
cout << std::endl;
// delete the set
set.reset();
cout <<"After delete first n";
// delete the set again
set.reset();
cout <<"After delete second n";
// set also deleted here through RAII
}

我在这里添加了另一个答案,因为以前的答案非常注重手动管理内存,而正确的答案是首先避免处理这个问题。

void main() {
std::vector<int> set (100);
cout << "memory allocatedn";
//use set
}

就这样,够了。这会给你100个整数,你可以随意使用。当控制流离开函数时,无论是通过异常、返回还是从函数末尾脱落,它们都将自动释放。不存在双重删除;甚至没有一次删除,这是应该的。

此外,我很震惊地看到其他答案中的建议,即使用信号来隐藏坏程序的影响。如果有人是一个足够的初学者,不理解这些相当基本的东西,请不要让他们走上这条路。