2

我有几个疑问,我记得有些地方我无法手动将变量放在内存中的特定位置,但后来我遇到了这段代码

#include<stdio.h>
void main()
{
int *x;
x=0x200;
printf("Number is %lu",x); // Checkpoint1
scanf("%d",x);
printf("%d",*x);
}

是我们不能把它放在一个特定的位置,还是我们不应该把它放在一个特定的位置,因为我们不知道它是否是一个有效的位置?

此外,在这段代码中,直到第一个检查点,我得到的输出是 512。然后是 Seg Fault。

有人可以解释为什么吗?0x200 不是有效的内存位置吗?

4

3 回答 3

3

在一般情况下 -您将获得的行为是未定义的- 一切都可能发生。

例如,在 linux 中,前 1GB 是为内核保留的,所以如果你尝试访问它 - 你会得到一个 seg 错误,因为你试图在用户模式下访问内核内存。

不知道它在 Windows 中是如何工作的。


linux声明的参考

目前,32 位 x86 架构是最流行的计算机类型。在这种架构中,传统上 Linux 内核将 4GB 的虚拟内存地址空间分成 3GB 用于用户程序和 1GB 用于内核。

于 2012-10-21T20:10:26.760 回答
0

添加到@amit 写的内容:

在windows中也是一样的。一般来说,所有保护模式操作系统都是相同的。由于 DOS 等不再存在,因此除了内核模式(km-drivers)和嵌入式系统之外的所有系统都相同。

操作系统管理允许您写入哪些内存页面,并放置标记,如果写入其他页面,CPU 会自动引发访问冲突。

于 2012-10-21T20:15:38.617 回答
0

直到“检查点”,您还没有访问内存位置 0x200,所以一切正常。

x在函数中有一个局部变量main。它的类型是“指向 int 的指针”。x分配值 0x200,然后打印该值。但是 x 的目标还没有被访问过,所以到目前为止,是否x持有有效的内存地址并不重要。

然后scanf尝试写入你传入的内存地址,也就是存储在x. 然后你会得到一个段错误,这肯定是尝试写入任意内存地址的可能结果。

那么你有什么疑问呢?当您遇到明显无效的代码时,是什么让您认为这可能有效?

写入特定的内存地址可能在某些条件下有效,但通常极不可能。在所有现代操作系统下,普通程序无法控制其内存布局。操作系统决定程序代码、堆栈和全局变量等初始内容的去向。操作系统可能还会使用一些内存空间,并且不需要告诉您它正在使用什么。相反,您请求内存(通过创建变量或通过调用内存分配例程),然后使用它。

因此,写入特定地址很可能会获得尚未分配的内存或用于其他目的的内存。这些都不好,即使您确实设法命中了一个实际上可写的地址。如果您破坏程序的其他变量之一使用的一些数据怎么办?或者你的程序的其他部分破坏了你刚刚写的值?

你永远不应该选择一个特定的硬编码内存地址,你应该使用一个你知道是变量的地址,或者你从类似malloc.

于 2012-10-21T23:38:31.017 回答