获取内存地址

时间:2015-08-04 21:10:08

标签: c pointers memory call

如何使用调用函数返回内存区域的地址:

// memory_region malloc'ed before this
uint64 address = get_memory_region_address (memory_region);
printf(">> memory_region (address) = 0x%lX\n",  address);   
printf(">> memory_region (address) = %p\n",  address);  

uint64 get_memory_region_address (int* memory_region) {
    uint64* address_of_memory = 0;

    address_of_memory_region = (uint64) memory_region;

    return address_of_memory;  
}

3 个答案:

答案 0 :(得分:2)

保证能够存储指针的正确整数类型为intptr_tuintptr_t

7.18.1.4能够保存对象指针的整数类型

以下类型指定一个带符号的整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较:{ {1}}

以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较:{ {1}}

不幸的是,这些类型是可选的

您的代码应为:

intptr_t

如果您想控制地址的格式,可以转换为uintptr_tuintptr_t get_memory_region_address (int* memory_region) { address_of_memory_region = (uintptr_t) memory_region; return address_of_memory; } uintptr_t address = get_memory_region_address (memory_region); printf(">> memory_region (address) = %p\n", (void *) address);

uintmax_t

ptrdiff_t

参考文献:

  • printf(">> memory_region (address) = %0xjX\n", (uintmax_t) address); :7.17通用定义printf(">> memory_region (address) = %0xtX\n", (ptrdiff_t) address);
  • ptrdiff_t:7.18.1.5最大宽度整数类型<stddef.h>
  • 格式化:7.19.6格式化输入/输出函数,具体为7.19.6.1 fprintf函数§7

答案 1 :(得分:2)

这个定义:

uint64 get_memory_region_address (int* memory_region)
{
    uint64* address_of_memory = 0;
    // ...
    return address_of_memory;  
}

没有任何意义。您将address_of_memory声明为指针为某种整数类型,然后将其作为该类型的整数返回。

基本上有两种方法可以获取对象指针的内存地址。

格式说明符%p

只需将其打印为:

printf(">> memory_region (address) = %p\n",  (void *) memory_region);

需要使用此转换为void指针以确保最大的可移植性。 printf()是可变函数,其参数(除了fmt)受默认参数提升的约束。这意味着如果在某些实施中:

sizeof(void *) != sizeof(int *)

成立,然后它会发出未定义的行为(严格来说,它甚至更早是UB)。

将指针的值转换为整数类型:

有一种可移植方式,使用intptr_tuintptr_t。两者都是{em>可选在<stdint.h>中定义。这样,你可以获得内存地址:

uintptr_t get_memory_region_address(int *memory_region)
{
    return (uintptr_t) memory_region;
}

然后将其打印为:

uintptr_t address = get_memory_region_address(memory_region);
printf(">> memory_region (address) = " PRIXPTR "\n",  address);

甚至更简单:

printf(">> memory_region (address) = " PRIXPTR "\n", (uintptr_t) memory_region);

答案 2 :(得分:0)

如果memory_region是指向先前分配的内存的指针,则其值应该已经是其第一个字节的地址。

尝试:

uint64 address = (uint64) memory_region;

我想我应该提一下标准C库定义的NULL = (void*) 0。如果您尝试将其作为指针读取/写入,则此0x0f地址将始终引发分段错误错误,这就是为什么它被命名为:Null,IfThisPointerVariableHasMeRunAwayFast,WantASegFaultJustReadMe值