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

时间:2016-06-10 08:48:52

标签: c++ c++11 exception-handling operators

删除双指针会导致程序崩溃等有害影响,程序员应尽量避免这种情况,因为它是不允许的。 但有时如果有人这样做,那么我们如何处理这个问题。 因为C ++中的删除是noexcept运算符,它不会抛出任何异常。它的书面类型也是无效的。那我们怎么抓住这种例外呢?  以下是代码段

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";

在这种情况下,我试图捕捉异常,但没有成功。 请求我们如何处理这些类型的场景。 提前谢谢!!!

4 个答案:

答案 0 :(得分:2)

鉴于后续delete[]上的行为未定义,除了编写

之外,您无能为力

set = nullptr;

在第一个delete[]之后立即

。这利用了删除nullptr是无操作的事实。

但实际上,这只是鼓励程序员马虎。

答案 1 :(得分:1)

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

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

  1. 内存所有权 - 明确使用vItpost['line_' + i]及其家人。
  2. 没有对std::unique_ptrstd::shared_ptr的明确原始调用。利用newdeletemake_unique
  3. 使用make_sharedallocate_shared等容器,而不是创建动态数组或在堆栈上分配数组。
  4. 通过valgrind(Memcheck)运行代码,以确保代码中没有与内存相关的问题。
  5. 如果您使用的是std::vector,则可以使用std::array来访问基础指针,而无需增加引用计数。在这种情况下,如果底层指针已被删除,则会抛出shared_ptr异常。这是我所知道的唯一一种在访问已删除的指针时会引发异常的情况。

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

答案 2 :(得分:1)

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
}

答案 3 :(得分:0)

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

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

就是这样。这就够了。这样就可以根据需要使用100个整数。当控制流离开函数时,无论是通过异常还是返回,还是通过从函数末尾掉落,它们都将自动释放。没有双重删除;甚至没有一个删除,这是应该的。

另外,我很惊讶在其他答案中看到使用信号来隐藏什么是破坏程序的影响的建议。如果有人对初学者不够理解这个相当基本的东西,请不要把它们放在那条道路上。