Address division to find index.

Started by
12 comments, last by Thevenin 18 years, 8 months ago
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?
Advertisement
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.
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]
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]
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++;
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]

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]
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.
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.
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;

This topic is closed to new replies.

Advertisement