5

是否可以在内存中为变量分配您想要的地址?

我试图这样做,但我收到一个错误,因为“需要左值作为赋值的左操作数”。

int main() {
  int i = 10;
  &i = 7200;
  printf("i=%d address=%u", i, &i);
}

我的方法有什么问题?C语言中有什么方法可以将我们想要的地址分配给变量吗?

4

9 回答 9

5

不是直接的。你可以这样做: int* i = 7200; .. 然后使用 i (ie. *i = 10) 但你很可能会崩溃。这仅在进行低级开发时才有意义 - 设备驱动程序等......具有已知的内存地址。

于 2012-11-26T05:19:47.660 回答
3

C 语言无法为您提供将名称“附加”到特定内存地址的方法。即你不能告诉语言一个特定的变量名应该引用一个位于特定地址的左值。因此,如前所述,您的问题的答案是“不”。故事结局。

此外,从形式上讲,没有其他可移植的方式来处理 C 中的特定数字地址。语言本身没有定义可以帮助您做到这一点的功能。

但是,特定的实现可能会为您提供访问特定地址的方法。在典型的实现中,将整数值转换A为指针类型会创建一个指向 address 的指针A。通过取消引用此类指针,您可以访问该内存位置。

于 2012-11-26T05:27:02.210 回答
3

假设您在现代操作系统上使用 x86 类型的处理器,则无法写入 aribtray 内存位置;CPU 与操作系统协同工作以保护内存,以便一个进程不会意外(或有意)覆盖另一个进程的内存。允许这样做会带来安全风险(请参阅:缓冲区溢出)。如果您尝试这样做,则会收到“分段错误”错误,因为 OS/CPU 会阻止您执行此操作。

有关这方面的技术细节,您需要从123开始。

相反,您要求操作系统为您提供一个可以写入的内存位置,使用malloc. 在这种情况下,操作系统内核(通常是唯一允许写入任意内存位置的进程找到一个空闲的内存区域并将其分配给您的进程。分配过程还将该内存区域标记为属于您的进程,以便您可以读取和写入它。

但是,不同的操作系统/处理器架构/配置可能允许您写入任意位置。在这种情况下,此代码将起作用:

#include <stdio.h>
void main() {
  int *ptr;
  ptr = (int*)7000;
  *ptr = 10;
  printf("Value: %i", *ptr);
}
于 2012-11-26T05:28:31.083 回答
1

不便携。但是一些编译器(通常用于嵌入式世界)有扩展来做到这一点。

例如在 IAR 编译器(这里是 MSP430)上,你可以这样做:

static const char version[] @ 0x1000 = "v1.0";

这会将对象version放在内存地址0x1000

于 2012-11-26T05:18:58.630 回答
0

不。

即使可以, 7200 也不是指针(内存地址),它是一个 int,所以无论如何这都行不通。

于 2012-11-26T05:17:13.170 回答
0

可能无法确定变量将具有哪个地址。但是作为你最后的希望,有一个叫做“指针”的东西,所以你可以修改地址上的值7200(尽管这个地址可能无法访问):

int *i = (int *)7200;
*i = 10;
于 2012-11-26T05:19:27.260 回答
0

使用 ldscript/链接器命令文件。但是,这将在链接时分配,而不是在运行时分配。

链接器命令文件语法很大程度上取决于特定的编译器。因此,您需要为您的编译器搜索链接器命令文件。

近似的伪语法有点像这样:

In linker command file:
.section start=0x1000 lenth=0x100 myVariables
In C file:
#pragma section myVariables
int myVar=10;
于 2012-11-26T05:20:06.823 回答
0

这是不可能的,也许可以通过编译器扩展来实现。但是,您可以在您想要的地址访问内存(如果您的进程可以访问该地址):

int addr = 7200;
*((int*)addr) = newVal;
于 2012-11-26T05:22:32.877 回答
0

我认为&a中的 '&'在编译时评估 i 的地址,我认为这是一个虚拟地址。所以根据你的编译器,它不是左值。改用指针

于 2012-11-26T05:34:54.853 回答