You mean...
struct mysurfacestruct
{
int a;
int b;
struct RGB *colors;
}
And than....
mySurface.colors = malloc(width*height);
Since otherwise it would be a struct with indefinent elements.
Annoyances with pointer offsets.
Quote:(&array[1] + 1) is EXACTLY equivalent to (&array[2])
That's because foo really means *(foo + i).
Quote:I'm fine with this if its bytes (Since +1 byte <=> the next byte), but when working with structures (Or any variable greater than 1 byte in size), I disagree with the standards.
I don't. It's perfectly rational. Get over it. Pointer arithmetic is intended to iterate over arrays - as such the step must be the size of the array element. If you want to apply a different offset, cast to char*.
template<class T>T* byte_offset(T* ptr, long offset){ return (T*)(offset + (char*)ptr);}
char *byte = (char*) &intary[5];char b0 = byte[0]char b1 = byte[1]char b2 = byte[2]char b3 = byte[3]
Think of it this way. int *p = foo();
p now points to an int. You can dereference p and do any sort of int related thing you want. If p+1 pointed to the next byte rather than the next element what would p point to? It would point to garbage. Dereferencing p may very well crash your app (because of alignment or other hardware design issues). The fact that in this particular case ((int *)((byte *)p)+1) might point to something useful is an accident caused by circumventing the type system.
Besides, the vast majority of time people work with elements and having to go p+sizeof(*p) all the time would be annoying and very error-prone.
p now points to an int. You can dereference p and do any sort of int related thing you want. If p+1 pointed to the next byte rather than the next element what would p point to? It would point to garbage. Dereferencing p may very well crash your app (because of alignment or other hardware design issues). The fact that in this particular case ((int *)((byte *)p)+1) might point to something useful is an accident caused by circumventing the type system.
Besides, the vast majority of time people work with elements and having to go p+sizeof(*p) all the time would be annoying and very error-prone.
Keep in mind that on some systems, unaligned memory accesses aren't possible:
int foo;*static_cast<int*>(static_cast<char*>(&foo) + 1); // Boom// I think this happens to be ok on x86 architecture, but will blow up on// almost everything Motorola ever made :/
x[y] is *(x+y) is *(y+x) is y[x], now and for ever.
As a result you can write something silly like cout << 4["Hello"] to print 'o'.
Even if it did do what you wanted in your example, you still end up with an integer when you dereference it, not the byte you wanted. You'd need to cast it regardless. The current method is better because you can skip multiplying by it's size, which you would need to do in every other case.
As a result you can write something silly like cout << 4["Hello"] to print 'o'.
Even if it did do what you wanted in your example, you still end up with an integer when you dereference it, not the byte you wanted. You'd need to cast it regardless. The current method is better because you can skip multiplying by it's size, which you would need to do in every other case.
The better way I spoke of would be:
It's laid out exactly the same in memory and you can access everything sensibly.
Do you now see how you were basically using a high-level-language as if it were a low-level-language (like asm). Make sure that your data structure matches the actual data. You were making things hard for yourself by not doing so.
Compiler pointer arithmetic addressing behaviour IS CORRECT, there is no question about that.
struct RGB { unsigned char r, g, b;};struct MySurface { int width, height; RGB colorData[0]; //May have to use a 1 here if your compiler wont allow zero length arrays.};
Of course, you'd allocate a MySurface with (width*height*3)+8 bytes.It's laid out exactly the same in memory and you can access everything sensibly.
Do you now see how you were basically using a high-level-language as if it were a low-level-language (like asm). Make sure that your data structure matches the actual data. You were making things hard for yourself by not doing so.
Compiler pointer arithmetic addressing behaviour IS CORRECT, there is no question about that.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement