• Advertisement
Sign in to follow this  

Address division to find index.

This topic is 4587 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Say I have an array of structures.. struct gtRGB goArray[50]; Than, say for some reason I'm giving the address of goArray[30], but I don't know that the index is 30... can I do something like this... ( (Passed Address) - &goArray[0] ) / sizeof(struct gtRGB) ...to get the index?

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
i would hazard to guess ...

in theory, yes ... it would work.
in practice, no ... because of the potential for padding within the struct to maintain address boundaries.

but that is just a guess.

Share this post


Link to post
Share on other sites
The first thing I do in all my projects is declare
#pragma pack(1)

... but struct padding shoudln't matter since sizeof() returns the size with consideration of struct padding....

I agree in theory it makes perfect sence, but we all know theory and practical are very different realms. [bawling]

Share this post


Link to post
Share on other sites
It's a bit of a hack but it should work, even in practice. If the struct/class is padded then that extra size will be included in the value given by sizeof(). Each element of the array will be located a multiple of sizeof(gtRGB) away from the start of the array so you can divide by sizeof(gtRGB) and get the correct integral result.

By the way, you should be able to do:

((Passed Address) - goArray) / sizeof(struct gtRGB)


Since array indexing is just syntactic sugar for pointer arithmetic:

'&array[0]' == '&*(array + 0)' == '&*array' == 'array'

The compiler probably loses the redunant deference/addressing anyway (certainly if optimisation is on) but it doesn't hurt to do it yourself and it makes the code simpler.

EDIT: Beaten to it :\. I should reply quicker and spend less time checking my post for errors.

[Edited by - Azune on July 30, 2005 11:58:30 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Azune
Since array indexing is just syntactic sugar for pointer arithmetic:

'&array[0]' == '&*(array + 0)' == '&*array' == 'array'


&*(array + 0)

Is the worst syntactic sugar I've ever encountered in C programming: merly because when I add 0x5 to an array, I expect it to offset it by 0x5, but when the pointer is a short, it will offset it 0xA... [flaming]

Sadly, very few agree with me... [bawling]

Anyways, thanks for the confirmation.

ratings++;

Share this post


Link to post
Share on other sites
Quote:
Original post by nmi
If your passed in pointer to element number 30 is p, then you can write:
q = &p[-30];
to get the address.
Or you can write:
q = p - 30;
Note that p and q are pointers to the struct.


Indeed, however, I do not know that the pointer to element number is 30 in my program; the index is unknown at runtime, I merly included it to help in the explaination of my problem.

Thanks though. [smile]

Share this post


Link to post
Share on other sites
IT GETS ME EVERYTIME! [bawling]
(And I was just talking about this with Azune)

I demand a new C Standards Draft! [caution]

I'm serious, look at the code below.. a (pointer-pointer) should be equal to the difference, always!. What occurs when you don't cast is complety different!


liC = (gaoMap[lusGridX + lusGridY*1500].loCreature - &gaoObjects[0])/sizeof(struct gtObject);

/* liC becomes 1 - WRONG */

liC = ((char *)(gaoMap[lusGridX + lusGridY*1500].loCreature) - (char *)(&gaoObjects[0]))/sizeof(struct gtObject);

/* liC becomes 135 - CORRECT */








[Edited by - Thevenin on July 30, 2005 11:27:56 AM]

Share this post


Link to post
Share on other sites
Don't divide by the sizeof the struct. Just subtract the pointer to the first index. Pointer arithmetic on typed pointers already includes the division.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Don't divide by the sizeof the struct. Just subtract the pointer to the first index. Pointer arithmetic on typed pointers already includes the division.


Good point, why didn't I notice that. Assuming the passed address is a gtRGB pointer then subtraction works. If it's not then you could cast both the array and passed address to char* and stick with the division.

Share this post


Link to post
Share on other sites
I do not understand.

/* Doing this... */
liC = ((char *)(gaoMap[lusGridX + lusGridY*1500].loCreature) - (char *)(&gaoObjects[0]))/sizeof(struct gtObject);

/* Is equilvalent to doing this...? */
liC = &gaoObjects[0] - gaoMap[lusGridX + lusGridY*1500].loCreature;


Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
Don't divide by the sizeof the struct. Just subtract the pointer to the first index. Pointer arithmetic on typed pointers already includes the division.
Just what I was going to say!

That, and don't forget to assert() that the resulting index is >= zero and < the size of the array.

Hopefully you mean this:
liC = gaoMap[lusGridX + lusGridY*1500].loCreature - &gaoObjects[0];
Then your answer is yes. Seeing the bennefits of pointer arithmetic yet?[grin]

Share this post


Link to post
Share on other sites
To be quite honest, I don't. [bawling]
(Well, I could use the method SiCrane posted, but I wouldn't understand it)

I did a google search on pointer arithmitic, but wasn't able to unravel this automated sizeof() division method.

I'd be most interesting in listening, if anyone cared to explain it to me. [smile]

Edit: It sounds to me (From SiCrane's post) that doing this...

int giInt, giIndex;
giIndex = &giInt + 1;

/* Will result in... giIndex == 1 */

Share this post


Link to post
Share on other sites
Quote:
Original post by Thevenin
To be quite honest, I don't. [bawling]
(Well, I could use the method SiCrane posted, but I wouldn't understand it)

I did a google search on pointer arithmitic, but wasn't able to unravel this automated sizeof() division method.

I'd be most interesting in listening, if anyone cared to explain it to me. [smile]

Edit: It sounds to me (From SiCrane's post) that doing this...

*** Source Snippet Removed ***
Nope, that isn't quite right.
1. When you add a pointer and an integer, it adds the integer multiplied by the structure size.
2. When you subtract a pointer and an integer, it subtracts the integer multiplied by the structure size.
3. When you subtract two pointers, the result is divided by the structure size.
4. It does not make sense to add pointers.

A similiar thing like this is with dates, and durations. A date is like the pointer, and the duration is like an integer. You can add July 11 2000, and a duration of 7 days, to get 18 July 2000, similiarly you can subtract 7 days and get 4 July 2000. You can also add 7 days + 3 days to get 10 days. However adding 11 August 2000, and 1 Janurary 2001 does not make sense.
Though you can subtract two dates to see how many days apart they are.

Now, here's how it realtes to pointer arithmetic: The date variables might be stored as a number of seconds, hence when you add 3 days, it needs to multiply 3 by the number of seconds in a day in order to add it, etc.

That's basically a perfect analogy for you. Make sense now?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement