8

我需要这样的条件:

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

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

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

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

喜欢:

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

7 回答 7

8

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

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

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

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

于 2013-05-13T10:25:06.900 回答
5

首先:

你不想那样做。

异常并不意味着处理错误,而是运行时错误条件,使您的函数无法满足它必须调用的其他函数的先决条件,或履行其自身后置条件的承诺(假设调用者已满足前置条件)。例如,参见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...
}
于 2013-05-13T09:50:47.727 回答
2

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

示例代码:

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

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

    ~FileGuard()
    {
        ::unlink(filename_);
    }
 }
于 2013-05-13T09:56:01.487 回答
0

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

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

于 2013-05-13T09:50:57.227 回答
0

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

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

于 2013-05-13T10:08:36.750 回答
0

如果您想确保始终删除您的“私人”文件,那么“包装器”程序怎么样。

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

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

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

    WaitForProcessExit(processId);

    _unlink("protectedfile.bin");

    return 0;           

}
于 2013-05-13T10:12:41.987 回答
0

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

char some_array[10];

是一种C语法,而不是 C++ 和

char c = some_array[11];

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

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

于 2013-05-13T10:02:26.553 回答