Trying to learn pointer math better I wrote this code. The intention was to increment the pointer threw the structure and print it's members. I know how to print it's member easier ways but would really like to know how my pointer math is messed up. Thank you.
typedef struct{
int num;
int num2;
char *string;
} astruct ;
int main (int argc, const char * argv[])
{
astruct mystruct = { 1234, 4567,"aaaaaaa"};
astruct *address;
address = &mystruct;
// this does print 1234
printf("address 0x%x has value of:%i\n",address, *address);
address = address + sizeof(int);
//this does NOT print 4567
printf("address 0x%x has value of:%i\n",address, *address);
address = address + sizeof(int);
//this crashes the program, I wanted to print aaaaaaaa
printf("address 0x%x has value of:%s\n",address, **address);
return 0;
}
Pointer arithmetic increments a pointer by the number of bytes pointed to. For example,
int a[2];
int *p = a;
assert( &a[0] == p )
assert( &a[1] == p + 1 )
Therefore, your line
address = address + sizeof(int);
actually changes address
to address + sizeof(int) * sizeof(astruct)
(using normal, not pointer arithmetic).
There is no guaranteed way to do what you are trying, because the compiler is allowed to introduce padding in a struct. Consider the struct
struct A {
char a;
int b;
};
The compiler will most likely give this struct the following layout:
+------------+-------------------+-------------+
| a (1 byte) | (3 bytes padding) | b (4 bytes) |
+------------+-------------------+-------------+
So you cannot get to b
by taking the address of a struct instance and adding 1.
In your specific case, the compiler probably doesn't introduce padding, so you may be able to use these lines to update address
:
address = (char *) address + sizeof(int); // OR...
address = (int *) address + 1;
Again, though, this depends entirely on the compiler laying out the struct the way you think it will, and any small change will probably break it, so you really shouldn't rely on this type of behavior.
When you add to a pointer, you actually add n * sizeof(*ptr)
bytes.
Hence on a 32 bit machine where your structure would take 12 bytes, adding sizeof(int)
bytes would actually add 48 bytes to the pointer.
To point at num2
you would first have to cast address to a pointer to an integer:
int *iaddress = (int *)address;
and then add one to that to reach your 4567 value.
The structures are designed to avoid such types of caluculation. Instead of iterating through memory, you can use mystruct.num
, mystruct.num2
and mystruct.string
. And still this will be a segfault since you do not allocate memory for 'aaaaaaa'.