How to get the actual address of a pointer in C?
c
Solution
The C99 standard says that a conversion from a pointer type to an integer type or vice versa is implementation defined behaviour (6.3.2.3.5 and 6.3.2.3.6), except where one uses `intptr_t` or `uintptr_t` defined in `<stdint.h>`, however 7.18.1.4 says these two types are not compulsory and an implementation does not need to provide them.
Problem
BACKGROUND: I'm writing a single level cache simulator in C for a homework assignment, and I've been given code that I must work from. In our discussions of the cache, we were told that the way a small cache can hold large addresses is by splitting the large address into the position in the cache and an identifying tag. That is, if you had an 8 slot cache but wanted to store something with address larger than 8, you take the 3 (because 2^3=8) rightmost bits and put the data in that position; so if you had address 22 for example, binary 10110, you would take those 3 rightmost bits 110, which is decimal 5, and put it in slot 5 of the cache. You would also store in this position the tag, which is the remaining bits 10. One function, cache_load, takes a single argument, and integer pointer. So effectively, I'm being given this int* addr which is an actual address and points to some value. In order to store this value in the cache, I need to split the addr. However, the compiler doesn't like when I try to work with the pointer directly. So, for example, I try to get the position by doing: `npos=addr%num_slots` The compiler gets angry and gives me errors. I tried casting to an int, but this actually got me the value that the pointer was pointing to, not the numerical address itself. Any help is appreciated, thanks! [edit] ``` 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); ``` When addr is passed in, it's actual address is 58, and it points to a value of 88. The output I'm getting from that printf is: addr is 58, taddr is 58, npos is 0 and ntag is 11 So it seems taddr is getting 58 (when printed with %p, still shows 88 when printed with %d), but npos and ntag are showing up as 0 and 11 (as though the mathematical operations are being run with 88) instead of 2 and 7 as I'd like. The code is used like this: ``` void load_words (int n, int words[]) { int i; for (i=0; i<n; i++) { load( (int *) (words[i] * 4)); cache_print(); } } ```