捕获所有类型的断言

时间:2013-05-13 09:45:18

标签: c++

我需要一个像这样的条件:

try
{
//bug condition
}
catch()
{
//Remove file
}

那就是我创建了一个非常机密的文件,第三方无法查看数据,但是当代码中出现任何错误时,我的文件被删除,因为我不确切知道,错误发生在哪里。

所以我想使用try和catch捕获该bug,并希望删除该文件。如何在C ++中捕获任何异常?

如果有错误,那将删除文件。

像:

try
{
    char TempArray[10];
    char c = TempArray[11];
}
catch
{
    cout<<"Array out of boundry";
    deleteFile("Confi.txt");
}

7 个答案:

答案 0 :(得分:8)

关于安全性的说法:如果您在硬盘上创建一个带有机密信息的文件,任何人都可以在进程运行且文件仍处于打开状态时关闭计算机,取出硬盘并读取其内容。

如果文件在服务器上,您可以通过在删除文件之前暂停进程来完成相同的操作。

即使你从文件系统中删除了文件,很可能仍然可以读取它,因为删除文件不会擦除其内容。

我建议在获得所需的专业知识之前不要处理机密信息 - 而不是从SO学习。但是,如果你必须这样做,我认为这里建议的看门狗进程+加密是可行的方法。

答案 1 :(得分:4)

首先:

你不想这样做。

异常不是用于处理错误,而是运行时错误条件,使您的函数无法满足其必须调用的其他函数的前置条件,或者保留承诺实现自己的后置条件(假设呼叫者满足前提条件)。例如,请参阅this article by Herb Sutter

不要写这样的东西:

try
{
    //bug condition <== NO! Exceptions are not meant to handle bugs
}
catch()
{
    //Remove file
}

而是:

assert( /* bug condition... */ );

回到问题:

您的程序有未定义的行为,并且很可能在执行此操作时根本不会抛出任何异常:

char TempArray[10];
char c = TempArray[11];

所以抓住所有异常都无济于事。这是一个错误,即编程错误,你是否应该以一种将控制转移到错误例程的方式处理错误是有争议的;而且,如果你承认你的程序中存在错误,你不能只是将控制转移到一个错误的处理程序吗?这可能会使情况变得更糟。

应该通过阻止来处理错误,利用断言,或许采用测试驱动开发等方法。

这就是说,关于捕捉所有异常的方法,你可以这样做:

try
{
    // ...
}
catch (...) // <== THIS WILL CATCH ANY EXCEPTION
{
}

但不鼓励使用catch (...)作为设计准则,因为它很容易导致吞噬错误条件,而这些错误条件意味着要处理并忘记它们。毕竟,发明异常是为了防止程序员忘记检查错误代码,而catch (...)使得这样做变得容易。

为了实现一切目标,最好让所有异常都来自std::exception,然后执行:

try
{
    // ...
}
catch (std::exception& e)
{
    // Do something with e...
}

答案 2 :(得分:2)

您要使用的是RAII。在这种情况下,create class在构造函数中取名文件,在析构函数中删除文件。在对文件执行任何操作之前,您使用适当的名称实例化此类的对象,然后如果由于任何原因退出该函数(干净地或通过异常),该文件将被删除。

示例代码:

class FileGuard : public boost::noncopyable {
    std::string filename_;

    public:
    FileGuard(const std::string &filename) : filename_(filename)
    {}

    ~FileGuard()
    {
        ::unlink(filename_);
    }
 }

答案 3 :(得分:0)

您的代码尝试访问定义边界之外的数据,这实际上是一个完全有效的尝试。根据情况和编译器,您的代码可能会或可能不会因访问冲突/段错误而崩溃,很可能不会。它肯定不会引发异常 - 在C ++中,异常只是由代码显式抛出,而不是由系统隐式抛出,如果它出错就会崩溃,而不像Java和C#这样的高级语言。

catch(...)语法将捕获每个可能的异常,但这不适用于这种情况。

答案 4 :(得分:0)

C ++允许您直接使用内存,并且部分C兼容。您尝试使用的语法:

char some_array[10];

C语法,而不是C ++和

char c = some_array[11];

是对内存的原始访问。这是unexpected behavior。这意味着没有人会告诉你将会发生什么。也许你只是错了字符,也许你的程序将被操作系统杀死。或者月亮将落在地球上。 =)

如果您需要高级功能 - 请使用纯C ++。查看标准库而不是“C”数组。您可以使用std::vectorat (size_type n)方法获取out_of_range例外 - 就像您需要的那样。

答案 5 :(得分:0)

正如其他答案所暗示的那样,您无法使用本机标准c ++正确解决此问题。事实上,一旦发生undefined behaviour,尝试做任何事情通常都是非常糟糕的事情。如果你不知道你的应用程序所处的状态,你怎么可能安全地运行代码?快失败。

解决问题的正确方法是让另一个单独的“监视程序”进程执行清理工作。它非常简单 - 只需让看门狗进程持续监控文件的存在。当它出现时,监视程序进程应该删除它。此删除将挂起,直到对文件的最后一个引用存在,然后它将执行删除[在* nix OS上它将文件重命名为临时位置,在Win系统上它将等待文件未被引用]。一旦主程序完成文件 - 通过正常方式或崩溃或其他任何方式,操作系统将正确删除该文件。

答案 6 :(得分:0)

如果你想确保你的'私人'文件一直被删除,那么'包装'程序怎么样。

创建一个运行受保护应用程序的新应用程序,然后等待它终止。当它终止时(无论是崩溃还是干净退出),删除你的私人文件然后退出。

运行包装器而不是运行应用程序。

int main(void)
{
    int processId = exec("your protected app");

    WaitForProcessExit(processId);

    _unlink("protectedfile.bin");

    return 0;           

}