繁体   English   中英

如何在C中获取指针的实际地址?

[英]How to get the actual address of a pointer in C?

背景:
我正在C中编写一个单级缓存模拟器来完成作业,我已经获得了必须使用的代码。 在我们对缓存的讨论中,我们被告知小缓存可以容纳大地址的方式是将大地址分成缓存中的位置和识别标记。 也就是说,如果你有一个8槽缓存但想要存储地址大于8的东西,你可以取3(因为2 ^ 3 = 8)最右边的位并将数据放在那个位置; 因此,如果您有地址22,例如二进制10110,您将获取那些最右边的位110,即十进制5,并将其放入缓存的插槽5中。 您还可以在此位置存储标记,即剩余的位10。

一个函数cache_load接受一个参数和整数指针。 所以有效的是,我正在给这个int * addr这是一个实际的地址,并指向一些值。 为了将此值存储在缓存中,我需要拆分addr。 但是,当我尝试直接使用指针时,编译器不喜欢。 所以,例如,我试图通过这样做来获得这个位置:
npos=addr%num_slots

编译器生气并给我错误。 我尝试转换为int,但这实际上得到了指针指向的值,而不是数字地址本身。 任何帮助表示赞赏,谢谢!

[编辑]

int load(int * addr) { 
  int value = (use_memory ? (*addr) : 0);
  intptr_t taddr=(intptr_t) addr;
  int npos=taddr % blocks;
  int ntag=taddr / blocks;
  printf("addr is %p, taddr is %p, npos is %d and ntag is %d\n",addr,taddr,npos,ntag);

当传入addr时,它的实际地址是58,它指向值88.我从该printf得到的输出是:

addr是58,taddr是58,npos是0,ntag是11

所以似乎taddr得到58(当用%p打印时,在打印%d时仍然显示88),但是npos和ntag显示为0和11(好像数学运算用88运行)而不是2和我一样。

代码使用如下:

void load_words (int n, int words[]) {
  int i;
  for (i=0; i<n; i++) {
    load( (int *) (words[i] * 4));
    cache_print();
  }
}

你应该使用类似的东西

int *pointer;
intptr_t address=(intptr_t) pointer;

这主要只是对@ Andrew的帖子的修正

所以你的功能应该成为

(哎呀忘了这是家庭作业。我会在一段时间内回复这个问题。不能直接给你答案:))

C99标准表示从指针类型到整数类型的转换(反之亦然)是实现定义的行为(6.3.2.3.5和6.3.2.3.6),除非使用<stdint.h>定义的intptr_tuintptr_t但是7.18.1.4说这两种类型不是强制性的,并且实现不需要提供它们。

int *pointer;
uint32_t address = (uint32_t) pointer;

当然,除了你不能保证int *适合uint32_t,所以你需要为你的平台选择正确的类型。

十进制88是0x58(十六进制58)。 将%p说明符与printf一起使用时,将打印出十六进制表示。 所以addr和taddr都是十进制88,你的计算是正确的。

这里还没有提到一个重要的事情。 当您使用%p说明符打印指针时,您应该转换参数:

printf("addr is %p\n", (void *)addr);

%p期望指向void,而printf的说明符/参数不匹配是未定义的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM