问题在于:您的程序暂时使用了一些敏感数据,并希望在不再需要时删除它.使用std::fill()on本身并不总是有用 - 编译器可能会决定以后不访问内存块,因此擦除它是浪费时间并消除擦除代码.
用户ybungalobill建议使用volatile关键字:
{
char buffer[size];
//obtain and use password
std::fill_n( (volatile char*)buffer, size, 0);
}
Run Code Online (Sandbox Code Playgroud)
目的是在看到volatile关键字后,编译器不会尝试消除对该调用的调用std::fill_n().
请问volatile关键字总是会阻止编译器修改代码吗?
编译器可以自由地优化您的代码,因为buffer它不是易失性对象。
该标准仅要求编译器严格遵守易失性对象的语义。这是 C++03 所说的
一致实施的最低要求是:
- 在序列点,易失性对象是稳定的,因为之前的评估已完成且后续评估尚未发生。[...]
和
抽象机的可观察行为是其对易失性数据的读取和写入以及对库 I/O 函数的调用的序列
在您的示例中,您所拥有的是使用易失性左值对非易失性对象进行读取和写入。C++0x 删除了我上面引用的第二个文本,因为它是多余的。C++0x 只是说
一致实施的最低要求是:
- 对易失性对象的访问严格按照抽象机的规则进行评估。[...]
这些统称为程序的可观察行为。
虽然有人可能会说“易失性数据”可能意味着“易失性左值访问的数据”,这仍然是相当夸张的,但 C++0x 措辞消除了对代码的所有疑虑,并且明确允许实现对其进行优化。
但正如人们向我指出的那样,这在实践中可能并不重要。优化此类事情的编译器很可能会违背程序员的意图(否则为什么有人会有指向 volatile 的指针),因此可能会包含错误。尽管如此,我还是有经验丰富的编译器供应商在面对有关其过度优化的错误报告时引用了这些段落。最后,volatile这是固有的平台特定的,无论如何你都应该仔细检查结果。