显式地向内存中的特定地址/位置分配或访问值?

Posted

技术标签:

【中文标题】显式地向内存中的特定地址/位置分配或访问值?【英文标题】:Explicitly assign or access values to or from specific address/location in memory? 【发布时间】:2014-01-22 16:32:19 【问题描述】:

我的确切问题是cc++ 中有任何规定可以明确地为特定地址分配一个值,例如假设我想将20 存储在内存中的0x1846010 地址并且我也想使用同一地址 (0x1846010) 访问值。

可能很容易,但如果可以的话,我真的很困惑如何做到这一点。

任何人都可以解释这是可能的,如果是,那么如何(用合适的例子),如果不是那么为什么?

提前致谢。

【问题讨论】:

什么是“c\c++”? C 和 C++ 是两种不同但密切相关的语言。您的问题的答案碰巧对两者都是相同的;并非所有可能的问题都是如此。 【参考方案1】:

你可以这样做:

*(int *)0x1846010 = 20;  // store int value 20 at address 0x1846010

检索工作类似:

int x = *(int *)0x1846010;

请注意,这假定地址 0x1846010 是可写的 - 在大多数情况下,这将生成像 Access violation writing location 0x01846010 这样的异常。

附:为了您的兴趣,您可以使用以下命令在运行时检查给定的地址是否可写(借用自here):

#include <fcntl.h>
#include <unistd.h>

int is_writeable(void *p)

    int fd = open("/dev/zero", O_RDONLY);
    int writeable;

    if (fd < 0)
        return -1; /* Should not happen */

    writeable = read(fd, p, 1) == 1;
    close(fd);

    return writeable;

正如here 所讨论的那样,通常您只会对没有操作系统且需要写入特定内存位置(例如寄存器、I/O 端口或特殊类型的内存)的嵌入式代码等执行此类操作(例如NVRAM)。

【讨论】:

请注意,“异常”也是 C++ 中的一个技术术语,与您使用它的方式无关。 @VikasVerma 这通常应该发生,即当它不可写时。 有什么方法可以知道特定地址是否有效? @VikasVerma 对于 Unix 操作系统,您可以像 this 一样进行操作。答案也更新了。 @VikasVerma 对 0 和 -1 无效。【参考方案2】:

是的。

假设0x1846010 是一个你有写权限的有效地址,你可以写:

*(int*)0x1846010 = 20;

并访问存储的值:

printf("%d\n", *(int*)0x1846010);

如果你真的在一个程序中这样做,它可能会崩溃,因为0x1846010 很可能不是一个你有写入权限的有效地址。

您究竟为什么要这样做?你怎么知道(如果你知道的话)0x1846010 是一个有效的地址?

这假设整数值0x1846010 到指针的转换甚至是有意义的。转换的结果是实现定义的,但“旨在 与执行环境的寻址结构一致”。

【讨论】:

有什么方法可以知道特定地址是否有效? @VikasVerma:也许吧。这完全是系统特定的。你为什么在乎? 0x1846010 的号码是从哪里来的?如果将值 20 存储在地址 0x1846010 可以解决您的问题,那是什么问题 我只是看到使用 & 运算符(如 cout @VikasVerma:所以你知道0x1846010 是你程序中某个变量的地址(你应该提到过)。至少,它是您的程序的特定运行中的地址;不能保证下次运行它时它会具有相同的地址。如果你有一个变量名,就用这个名字;根本没有充分的理由像这样使用它的原始地址。 感谢您的回答:)【参考方案3】:

这取决于您使用的平台和操作系统(如果有)。从语言的角度来看,英雄胡永涛的解决方案通常是有效的。真正的问题是您环境中地址的含义(换句话说:您的目标到底是什么?)。如果您使用的是现代操作系统,地址几乎肯定是虚拟的(即由 CPU 的内存管理单元以透明的方式转换)。如果您的目标是在某个特定的 PHYSICAL 单元上进行写入(即,因为它承载了一个设备并且您想驱动它),您必须首先确保操作系统已为您创建了物理地址的视图。这样做的方式完全取决于操作系统的 API。即使您没有任何操作系统,您正在处理的地址也可能不是“物理的”。这取决于 CPU 和它的初始化方式。 完全不同的情况是,您的目标是更改特定地址,因为“您知道”在您的环境中它具有特定含义。 IE。操作系统可能会在一个已知的虚拟地址存储一些有用的信息。许多操作系统用于在固定地址存储环境变量和命令行参数的副本,因此 C 运行时库可以轻松找到它们。如果你是这种情况,那么英雄胡永涛的建议通常是好的。

【讨论】:

以上是关于显式地向内存中的特定地址/位置分配或访问值?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript中的内存泄漏以及如何处理

java中的内存分配

为什么将值分配给数组中的特定位置,将同一值分配给同一数组中的其他随机位置?

2017/03/19学习笔记

super 在Java继承中的作用??

内置数据类型