Jump to content
  • Advertisement
Sign in to follow this  

Annoyances with pointer offsets.

This topic is 4702 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

As part of my DIB implementation, I'm reminded of this little annoyance.
int luiMain[2];

luiMain[0] = 10;
luiMain[1] = 10;

*(&luiMain[0] + 1) == luiMain[1]

In order to add 1 byte, instead of 4 bytes, you gotta cast it...
#include <stdio.h>
void main()
{
	int *laiMain;
	int luiX;
	laiMain = malloc(4*5);
	laiMain[0] = 1;
	laiMain[1] = 5;
	laiMain[2] = 10;
	laiMain[3] = 15;
	laiMain[4] = 20;
	
	for(luiX=0;luiX<=8;luiX++) printf("laiMain[%d]=%d\n", luiX, *(((char *)&laiMain[0]) + luiX));
}

Anyone know a way to disable this? lol, why did they decide on this?! It really doesn't help at all! [Edited by - Thevenin on July 4, 2005 8:41:48 PM]

Share this post


Link to post
Share on other sites
Advertisement
Looks like you're trying to inspect individual bytes within each int.

Do you use/understand hex? If so... why not use this instead?


int luiX;
laiMain[] = { 1, 5, 10, 15, 20 };

for(luiX = 0; luiX < sizeof(laiMain); luiX++)
printf("laiMain[%d]=%.8X\n", luiX, &laiMain[luiX]);


Seems like that would be the simplest way to inspect bytes (in groups of four)

I'm at a loss as to why you need to iterate through the array of ints one byte at a time, though [smile]

Share this post


Link to post
Share on other sites
The need arose because I went and did this...

void *Surface = [int][int][struct loRGB][struct loRGB][struct loRGB]...

The first two ints are the width and height, and the rest (Roughly 250k) are all RGB structs.

Inaddition, instead of calling it a void, I went and called it...

struct tRGB *Surface = [int][int][struct loRGB][struct loRGB][struct loRGB]...

So now its impossible to access the first two ints properly without breaking off of the "Multiple of 3" rule imposed by the automated structure cast.

I work with Hex quite often when cheating on DungeonCrawl, but in the programming environment I've never figured out what 0x means, is that just a symbol representing that the following is in Hex?

Share this post


Link to post
Share on other sites
They did it that way because if you have a pointer to something it makes no sense for p+1 to point into the middle of it. It also falls out naturally from the syntax for arrays.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anon Mike
They did it that way because if you have a pointer to something it makes no sense for p+1 to point into the middle of it. It also falls out naturally from the syntax for arrays.


But, but but but.. but

Array[x+1] == I'm ok with that +1 shifting it the sizeof(element).
Array[x] + 1 == This is ludakris, it should shift it 1 byte, not sizeof(element) [headshake]

Share this post


Link to post
Share on other sites
Quote:
Original post by Thevenin
Array[x+1] == I'm ok with that +1 shifting it the sizeof(element).
Array[x] + 1 == This is ludakris, it should shift it 1 byte, not sizeof(element) [headshake]


Those are quite diffrent, one references the element at element (x + 1) the other is the element at x and has one added to it. But let's pretend you ment
&Array[x] + 1
then that wouldn't reference an element but is equal to Array + x + 1, and I guess understanding that is the source of the your problem. Array[x] is just convinent shorthand for *(Array + x), actually it extends so far as to actually being able to write x[Array] (disregarding the fact that anyone who actually use that construct should be shot.

Share this post


Link to post
Share on other sites
Quote:
Original post by Thevenin
The need arose because I went and did this...

void *Surface = [int][int][struct loRGB][struct loRGB][struct loRGB]...

The first two ints are the width and height, and the rest (Roughly 250k) are all RGB structs.

Inaddition, instead of calling it a void, I went and called it...

struct tRGB *Surface = [int][int][struct loRGB][struct loRGB][struct loRGB]...

So now its impossible to access the first two ints properly without breaking off of the "Multiple of 3" rule imposed by the automated structure cast.

I work with Hex quite often when cheating on DungeonCrawl, but in the programming environment I've never figured out what 0x means, is that just a symbol representing that the following is in Hex?
Can you please show what you mean in terms of real C++ code with regards to tRGB above. You can't possibly mean a 5-dimensional array!

Also, please explain what you mean by a "multiple of 3 rule". Those first two ints are aligned to int boundaries as far as I'm concerned from what you've posted this far.

I do not see a reason for you to attempt to circumvent the automatic pointer offset arithmetic, thus far. If it's behaviour seems wrong, then you are probably doing something in a bad way. Show some real code so we can show you the way that you should really be doing it.

Share this post


Link to post
Share on other sites
KISS. (I assume plain C.)


typedef struct tRGB_s {
int x;
int y;
// The easiest thing is to just add a level of indirection.
// C's unbelievably weak typing also lets you get away with just declaring
// an array[1] here, and then over-allocating memory accordingly to create
// the struct.
struct loRGB* data;
} tRGB;

tRGB* createTRGB(int x, int y) {
tRGB* thing = malloc(sizeof tRGB); if (!thing) return NULL;
thing->x = x; thing->y = y; thing->data = malloc(sizeof (struct loRGB) * x * y);
if (!thing->data) { free(thing); return NULL; }
return thing;
}

int destroyTRGB(tRGB* target) {
if (!target) return -1;
free(target->data); // it is an invariant that this won't be NULL.
free(target);
return 0;
}

tRGB* cloneTRGB(tRGB* src) {
tRGB* result = createTRGB(src->x, src->y); if (!result) return NULL;
for (int i = 0; i < src->x * src->y; ++i) { result->data = src->data; }
return result;
}

int assignTRGB(tRGB* src, tRGB* dest) {
if (!(src && dest)) return -1;
tRGB* other = cloneTRGB(src); if (!other) return -1;
dest->x = other->x; dest->y = other->y;
free(dest->data); dest->data = other->data; free(other);
return 0;
}



In C++ this kind of thing becomes much easier:


struct tRGB {
int x;
int y;
loRGB* data;
tRGB(int x, int y) : x(x), y(y), data(new loRGB[x*y]) {}
tRGB(const tRGB& other) x(other.x), y(other.y), data(new loRGB[x*y]) {
for (int i = 0; i < x*y; ++i) { data = other.data; }
}
tRGB& operator=(const tRGB& rhs) {
// copy and swap idiom, for exception safety. I used something similar in
// the C code.
tRGB other(rhs);
x = other.x; y = other.y; std::swap(data, other.data);
}
~tRGB() { delete[] data; }
};

Share this post


Link to post
Share on other sites
I do not mean a 5-dimensional array.

(&array[1] + 1) is EXACTLY equivalent to (&array[2])

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.

Quote:
Original post by iMalcIf it's behaviour seems wrong, then you are probably doing something in a bad way. Show some real code so we can show you the way that you should really be doing it.


Ok.

You have a very large block of linear memory...
[][][][][][][][][][][][][][][][][]

You store int's in the first two
[int][int][][][][][][][][][][][][]

Than you store struct RGB (A structure of 3 unsigned characters) in the remaining.
[int][int][sturct RGB][sturct RGB][sturct RGB][sturct RGB][sturct RGB]...

And you call this a surface.

Now when you call my sDrawSurface() function, you don't have to specify the width and height of the surface your drawing, because it already knows, because its already in the surface itself (My reason for doing it this way).

Its really just this simple.

The "Multiple of 3" rule is reference to the fact, that I cannot say arrSurface[{Some Decimal Value Here}] and get the height.

Observe...
struct RGB MyRGBArray;

MyRGBArray[0] == 0th byte.
MyRGBArray[1] == 3rd byte.
MyRGBArray[2] == 6th byte.
MyRGBArray[3] == 9th byte.
MyRGBArray[4] == 12th byte.

However, my the width and height are on the 0th byte && 4th byte.

And so I was hoping....

&MyRGBArray[0] + 4 == 4th byte.

However, it actually equals....

&MyRGBArray[0] + 4 == 12th byte.

Which is ludakris!

Share this post


Link to post
Share on other sites
arrays are meant to store 1 data type. array indexing and pointer arithmetic work the same way. use a byte as your pointer type if you want to increment by the size of a byte.

How about instead of trying to hack something into working, you use the right tool for the job, such as a struct?

struct RGB
{
unsigned char r,g,b;
}

struct mysurfacestruct
{
int a;
int b;
RGB color1;
RGB color2;
RGB color3;
}

then you can have an array of these structs if you want.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!