我一直认为对象在相同的内存位置开始和结束其生命周期,但是最近我遇到了需要确定的情况。具体来说,我正在从标准中寻找一种保证,即无论编译器执行何种优化,构造对象的地址都将与其调用的析构函数相同,并且其析构函数确实是相同的,除非程序终止,否则请确保从该位置调用它。
我一直认为这些东西是理所当然的,但是仔细检查后我找不到保证,而且在复制和移动省略周围有些语言我不确定如何解释。我希望这里的一些更懂标准的人可以将我引向章节和经文。
作为此问题的后续部分,我正在想象一个存储敏感数据(如加密密钥)的类。为简化起见,假设不涉及继承。
struct Credential {
std::array<uint8_t, 32> secretStuff;
~Credential() { memset_s(secretStuff.data(), 32, 0, 32); }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试确定是否可以保证运行此类型的对象的析构函数,或者是否需要做一些花哨的事情,例如使用分配器以确保擦除内存。我对抵御编译器优化的适应性很感兴趣,因此我正在寻找标准的章节,以确保无论如何我都会得到正确的行为。
在前面的问题中,已经确定static
保证自动分配和存储中的对象可以运行其析构函数。我对static
此案不感兴趣;就我而言,确保程序终止后,先前使用的内存内容不会泄漏是操作系统的职责。对于程序员故意破坏事物的情况,我也不感兴趣...毕竟,没有什么可说的是他们不能只复制数据。
假设您是一名编译器作者,并且想在遵守标准的同时打破它。您有什么办法可以避免调用析构函数(程序终止除外)?也许一些奇怪的异常处理行为?如果不允许您这样做,为什么不这样做呢?
有没有什么方法可以在不重述的情况下引用元组字段的类型?类似这样的事情:
pub struct Foo(i16, u64);
impl Foo {
pub fn get_bar(&self) -> Self::0 { self.0 }
pub fn get_baz(&self) -> Self::1 { self.1 }
}
fn main() {
let foo = Foo(123, 456);
println!("bar: {}", foo.get_bar());
println!("baz: {}", foo.get_baz());
}
Run Code Online (Sandbox Code Playgroud)
(这不起作用,因为这Self::0
不是一个东西。但也许它是,我只是不知道它叫什么。)
我正在 Windows 内部进行一些探索以进行一般性教育,并且我正在尝试了解 Image File Execution Options 背后的机制。具体来说,我为 calc.exe 设置了一个调试器条目,"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NoExit -Command "& { start-process -filepath $args[0] -argumentlist $args[1..($args.Length - 1)] -nonewwindow -wait}"
作为有效负载。这导致递归,启动了许多 powershell 实例,考虑到我正在拦截他们对calc.exe
.
不过,这就引出了一个问题:普通调试器如何在不引起这种递归行为的情况下启动被测程序?