为什么在C中每次执行后变量的地址都会发生变化?

时间:2010-05-17 04:17:16

标签: c programming-languages pointers

int i=10;
printf("Address of i = %u",&i);

Output:
Address if i = 3220204848

Output on re-execution:
Address of i = 3216532594

每次执行程序时,我都会得到i的新地址。这意味着什么?

5 个答案:

答案 0 :(得分:7)

它表示每次运行程序时都会加载一个不同的(虚拟)地址。这是一个名为Address Space Layout Randomization (ASLR)的功能,是大多数现代操作系统的一项功能。

答案 1 :(得分:1)

这就是操作系统的工作原理。当你声明一个变量时,你要求底层系统分配一个内存块(地址)来存储那些数据(或者如果你正在处理指针那么指向另一个块的指针,但是这里你有一个原语,所以它只是存储的数据)。程序并不关心内存的位置,只关系它存在,因为它知道如何跟踪它所给出的内容。

作为程序员,除非你做一些令人难以置信的低级工作,否则这真的不是什么大不了的事。对大多数人来说,最难掌握的是,当你使用指针时,你不能用与原语相同的方式来区分事物,因为指针会考虑它们的值(当使用==作为赤道时)他们的记忆地址。

答案 2 :(得分:0)

在c程序执行时,另一个进程正在运行。再次执行代码时,您将分配新地址,之前分配的地址将分配给另一个进程。

答案 3 :(得分:0)

我指的是我认为对quora更有用的答案,因此我在下面提到他的答案,有关详细解释,请访问链接

信用-迈克尔·维克斯勒

链接-https://www.quora.com/Do-pointer-addresses-change-every-time-the-program-is-executed-in-C

他的个人资料链接-https://www.quora.com/profile/Michael-Veksler

指针地址通常由于地址空间布局随机化而改变。禁用该功能(Windows和Linux)后,程序执行之间的地址不再更改。

指针地址在两次执行之间是恒定的。实际上,对于具有虚拟内存的操作系统而言,每次运行时分配具有相同地址的内存更为容易(没有虚拟内存的系统(例如DOS)是不同的。

确定性地址使调试程序变得更容易,因为在恒定的内存布局上始终可以再现内存损坏错误和指针相关的错误。但是不幸的是,这会带来安全风险,因为病毒也可能依赖于一致的内存损坏。

作为一项安全措施,操作系统开始随机化堆栈,全局变量和堆[1]的位置。这样,每次激活时地址都会改变,从而使潜在攻击者的生活更加困难。但这会使调试更加困难,并且错误也会更加随机。

为使调试更容易,可以关闭地址随机化。在Linux上,可以通过将0写入/ proc / sys / kernel / randomize_va_space来全局关闭随机化。可以仅通过一个过程将其关闭,例如使用

$ setarch uname -m -R program_path Linux调试器会自动关闭地址空间随机化。如果您在Linux中调试程序,则每次重新启动程序时,它都会一次又一次具有相同的指针。

从Windows Vista开始,Windows可以将地址随机化,而从Windows 7开始,默认情况下它将对其随机化。可以通过编辑注册表HKLM \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ Memory Management \ MoveImages或通过链接/ DYNAMICBASE:NO标志来禁用它。否则,指针将在调用之间改变。我不确定在Visual Studio中以调试模式进行编译时默认情况下会发生什么。

请注意,根据C标准,不能保证。特定的系统(例如Linux或Windows)可以根据需要做出自己的保证。但是,某些系统(例如MS-DOS)无法做出类似的保证。

答案 4 :(得分:0)

使用以下方式禁用ASLR:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

您将始终看到相同的地址。