Originally published by Robert Beisert at fortcollinsprogram.robert-beisert.com

Pointer Arithmetic Matters

What’s the first thing you think when I say the word: “Pointer”. Generally, you either think of a particular register (unlikely) or a hexadecimal number representing a location in memory (likely). Personally, I’m in the latter category, which is why this problem arose.

I was in the middle of programming, and I decided to allocate an array of a given structure. If we pretend that my structure was called “panda”, the code would look something like this:

//I had some number of structures to allocate, but I wasn't sure in advance how many
int j = get_quantity();
struct panda * NP = (struct panda *) calloc (j, sizeof(struct panda));

All very straightforward so far. I figured out how many structures I would need and allocated a contiguous (and zero-filled) memory space for them. This basically created an array of struct panda's, with every field of every struct panda set to 0.

Here's where it got a bit tricky. I was going to populate all of this space using a loop that looked something like this:

[code language="c"]
//Repeat once for every struct I allocated
for(i=0; i< j; i++)
NP + (i * sizeof(struct panda)),

This code morsel threw a SegFault every time.

Even though there’s not much there, it took me hours to figure out how I screwed this up.

Here’s a hint: it’s right there in fill_panda.

Give up?

You see, I’m acting as though NP is a (64-bit) hexadecimal number corresponding to a Byte in memory. If that were 100% true, there would be no problem. However, NP isn’t just some hexadecimal value – it’s a POINTER.

Not just any pointer, but a pointer to a struct panda.

It turns out that C pointers know their size. If you say NP+1, it is functionally similar to NP[1].

I basically dynamically allocated an array, right? And we can use array notation on an array, right? Good.

So, when I meant to say:


I actually said:

[code language="c"]
NP[ i * sizeof(struct panda) ]

Whoops. Because struct panda is not the size of a single character, I was guaranteed to go out of the bounds of my allocated space.

To Drive the point home, so no one can forget:
NP + 1 == NP[1].
NP == NP[0].
NP + i == NP[i].

Don’t overthink it, like I did.

photo by: