0

运行以下命令时,它会一直打印相同的内存地址。

#include <stdio.h>

int array[5] = {2, 4, 6, 8, 10};
int *pointer;


int main()
{
        pointer = array;
        printf("%p:\t%d\n", pointer, *pointer);
        return 0;
}

我不知道这是否是一个问题,但我仍然很想知道为什么会这样,当在 main() 中声明它时会不断返回新地址。

4

4 回答 4

2

纯属巧合。
您不能依赖地址在不同的运行中相同。

于 2012-12-04T09:55:31.570 回答
1

请注意,在大多数现代桌面(当然还有服务器)操作系统上,进程处理的地址是虚拟的。这意味着当操作系统加载程序以在您的进程中运行时,它会在 RAM 的物理页面和进程“看到”的虚拟页面之间建立映射。

每次运行程序时,这个映射对你来说似乎都是一样的,但这完全是巧合。操作系统也可以应用随机化或任何其他使映射发生变化的方法。

请注意,由于存在虚拟地址,您的任意数量的程序完全有可能同时(并行)运行并且仍然看到完全相同的数组地址。

于 2012-12-04T10:27:13.920 回答
0

这个问题是一个争论不休的话题,并且由来已久。

最初,当程序在物理内存中运行时,事物的地址过去依赖于执行前内存中的内容。

后来,使用现代 CPU,每个进程都会获得自己的地址空间,因此没有多样性。

然后,安全人员来了,说故意随机化程序起始地址和代码位置可以防止一系列安全攻击。他们中的一些人被一群软件工程师私刑处死,他们说提高一致性对于进行更有用的软件测试很重要。然而,一些编译器(例如 Visual Studio 2010)会默认执行代码位置的随机化。

在大多数情况下,这仍然是不可能的,而且对数据的需求也较少。这就是为什么你会得到相同的结果。

于 2012-12-04T10:25:20.380 回答
0

您通常在发布的代码中为“数组”获得相同地址,但如果您在 main 内部声明数组则获得不同地址的原因是 main 外部的数组具有全局范围,因此分配在单个固定位置,而如果在 main 中声明的数组,则在进入 main 时在堆栈上分配(并且可以想象,如果您从其他地方调用 main,则可以分配多次)。

其他答案中描述的随机化地址的安全功能适用于堆栈,而不适用于具有静态持续时间的变量,因为常见的漏洞利用通过用恶意代码覆盖堆栈来工作,然后通过覆盖返回地址来跳转到它,返回地址也被存储在堆栈上。用恶意代码覆盖非堆栈变量仍然会给攻击者留下执行它的问题,因此安全问题较小。

于 2012-12-12T21:02:14.390 回答