【问题标题】:How can I store a value at a specific location in the memory?如何将值存储在内存中的特定位置?
【发布时间】:2011-10-03 10:04:23
【问题描述】:

也许这是一个简单的问题,但我真的很想知道它。

如果我想在内存(堆)的特定地址存储一个值,比如一个 int,我该怎么做?

说,我想将 int 值 10 存储在 0x16 处。我想通过调用 new 或 malloc 来做到这一点: int *p=new int(10);然后我想将存储值的地址设置为0x16。起初我只是想像 &p=0x16 这样的东西,但这不起作用。我需要这样做以将一些附加信息存储在内存中某个值的前面(之前由 malloc 或 new 分配的内存空间)。

我正在使用 linux 和 C++(但 C 也可以)。

我想要实现的是:一个进程调用大小为 x 的 malloc,我想在分配的内存前存储一个特定值(大小),以便稍后(调用 free 时)访问该大小。由于调用了 malloc,我知道操作系统为值分配空间的指针,我只想将分配内存的大小存储在分配内存前面的 4 个字节中。我所做的(在我编写的 malloc 挂钩中)是分配更多内存(通过内部 mallok 调用),但我还需要能够将此大小值存储在特定位置。

感谢所有帮助。

【问题讨论】:

  • 你真的真的应该阅读一些关于指针的教程
  • 想要你想做的事是不合法的。除非您了解操作系统和内存分配器(显然您不了解),否则它只会崩溃或做其他意想不到的事情。告诉我们您真正想要实现的目标,而不是您认为需要做的事情。

标签: c++ c memory malloc new-operator


【解决方案1】:

你可以这样做:

*(int *)0x16 = 10;  // store int value 10 at address 0x16

请注意,这假定地址 0x16 是可写的 - 在大多数情况下,这会产生异常。

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

您可以像这样定义这些特殊地址:

volatile uint8_t * const REG_1 = (uint8_t *) 0x1000;
volatile uint8_t * const REG_2 = (uint8_t *) 0x1001;
volatile uint8_t * const REG_3 = (uint8_t *) 0x1002;
volatile uint8_t * const REG_4 = (uint8_t *) 0x1003;

然后在您的代码中,您可以像这样读取写入寄存器:

uint8_t reg1_val = *REG_1; // read value from register 1
*REG_2 = 0xff;             // write 0xff to register 2

【讨论】:

  • 我会在这里使用reinterpret_cast,而不是C 风格。值得注意的是代码的低级、机器相关性。
  • 这适用于一些嵌入式/直接内存系统(驱动程序等)。但我认为 OP 并非处于这种情况——他们似乎对进程内存的概念感到困惑。因此我认为这实际上不会帮助他们(在 linux 上你根本不能这样做)
  • @edA:您可能是对的-原始形式的问题相当模糊/困惑,但 OP 似乎随后添加了有关他想要实现的目标的更多细节。我不确定为什么我的回答值得一票否决?
  • @James:这个问题被标记为 C 和 C++,所以我在这里假设最小公分母。
  • @Paul,我不是投反对票的人。从完整的问题来看,我猜他们只是在寻找共享内存。
【解决方案2】:

我相信实现目标的最佳方法是实现自己的 malloc,它将多分配 4 个字节并存储内存块的大小 喜欢:

void* mymalloc(int size)    
{
    char* ptr = malloc(size+sizeof(int));
    memcpy(ptr, &size, sizeof(int));
    return ptr+sizeof(int); 
}

【讨论】:

  • @Bo 是真的。这是一个小插图。实现应该更复杂
【解决方案3】:

我想要实现的是:一个进程调用大小为 x 的 malloc,我想在分配的内存前存储一个特定值(大小),以便稍后(调用 free 时)访问该大小。由于调用了 malloc,我知道操作系统为值分配空间的指针,我只想将分配内存的大小存储在分配内存前面的 4 个字节中。

所以行不通。您只能在法律上允许写入您的库分配的内存地址。在 C 中,这意味着 malloc 及其朋友。在 C++ 中,这也意味着 malloc(尽管在 C++ 中应该避免这种情况)和 new

任何尝试写入这些分配方案分配的显式空间之外的任何内存都会导致未定义的行为。这通常意味着“可能会发生坏事。”

例如,malloc 返回的地址前的 4 个字节可能是堆的一部分。也就是说,mallocfree 用来完成工作的数据结构。通过写信给他们,你现在已经破坏了堆;现在,每次内存分配或释放都充满了危险,并且可能会严重失败。

或者,地址之前的 4 个字节可能超出了您的虚拟地址空间。在这种情况下,操作系统会事后杀死你的程序。当您遇到“一般保护故障”或“分段故障”时,就会发生这种情况。好消息是这通常是即时的,因此您可以在调试器中看到它发生的位置。与堆损坏不同,除非您知道堆是如何工作的(或没有堆调试工具),否则您无法判断出了什么问题。

【讨论】:

    【解决方案4】:

    您可以使用 Placement New 将类型放置在 freestore(a.k.a heap)上的特定内存位置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 2013-09-30
      • 2021-11-14
      • 2021-07-05
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多