使用模板强制编译器初始化基元/ POD类型值(https://stackoverflow.com/a/11493744/16673或http://www.codeproject.com/Articles/825/Using-templates-for-initialization)是一种常见模式。
出于安全原因,一旦它超出范围,是否存在可用于擦除值的类似模式,以确保在变量被破坏后该值不会留在堆栈中?我担心一个天真的类似实现可能不起作用,因为编译器可以自由地忽略对超出范围的值的任何赋值,因为该值可以被简单地证明不再被使用。是否有一些一致且合理的便携解决方案,例如使用volatile?
答案 0 :(得分:4)
Windows API中有一个名为SecureZeroMemory的功能。你可以看看它的实现。
但是,一般来说,编译器被迫遵守易失性写入。如果您将变量设置为volatile,则它应该无法删除写入。
答案 1 :(得分:3)
您可以使用一些c ++ 11功能使其更具可移植性,但这可能足以作为起点:
<强>类强>
template<typename T>
class t_secure_destruct {
static const size_t Size = sizeof(T);
static const size_t Align = alignof(T);
public:
t_secure_destruct() : d_memory() {
new(this->d_memory)T;
}
~t_secure_destruct() {
reinterpret_cast<T*>(this->d_memory)->~T();
this->scribble();
}
// @todo implement or delete op-assign and remaining constructors
public:
T& get() {
return *reinterpret_cast<T*>(this->d_memory);
}
const T& get() const {
return *reinterpret_cast<const T*>(this->d_memory);
}
private:
void scribble() {
for (size_t idx(0); idx < Size; ++idx) {
this->d_memory[idx] = random();
}
}
private:
__attribute__((aligned(Align))) char d_memory[Size];
};
<强>演示强>
#include <iostream>
class t_test {
public:
t_test() : a(-1) {
std::cout << "construct\n";
}
~t_test() {
std::cout << "destruct\n";
}
public:
void print() const {
std::cout << "a = " << a << "\n";
}
public:
int a;
};
int main(int argc, const char* argv[]) {
t_secure_destruct<t_test>test;
test.get().print();
test.get().a = 100;
test.get().print();
return 0;
}
当然,如果您愿意,也可以使用堆分配来支持该分配。如果你需要超越优化器,你可能需要让涂鸦器远离它。