如何将值存储在内存中的特定位置?

时间:2011-07-12 08:04:21

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

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

如果我想在内存中的某个特定地址(堆中)存储一个值(例如一个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调用)但我还需要能够在特定位置存储此大小值。

我感谢所有人的帮助。

4 个答案:

答案 0 :(得分:11)

你可以这样做:

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

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

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

您可以将这些特殊地址定义为:

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

答案 1 :(得分:8)

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

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

答案 2 :(得分:2)

  

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

那是所以无法正常工作。您只能合法地写入您的库分配的内存地址。在C中,这意味着malloc及其朋友。在C ++中,这也意味着malloc(尽管你应该在C ++中避免这种情况)和new

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

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

或者,地址前的4个字节可能在虚拟地址空间之外。在这种情况下,操作系统将在posthaste中删除您的程序。当你遇到“一般保护错误”或“分段错误”时会发生这种情况。好消息是,这通常是即时的,因此您可以在调试器中看到它发生的位置。与堆损坏不同,除非您知道堆的工作方式(或没有堆调试工具),否则无法分辨出错误。

答案 3 :(得分:0)

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