Reputation: 11
Right now I have a code thatdoes pointer arithmetic like this
var1 + sizeof(structA)
Var1 is a pointer, and structA is a struct with sizeOf 4 bytes. The problem is that when I do this, the address gets shifted down 16 bytes instead of 4. I found that the problem is because in C even though I typed that it's actually
var1 + sizeof(structA) * sizeof(int)
as int is the return of sizeof. Is there a way I can fix this? For a similar problem, I'm doing
var1 - sizeof(structA)
But instead of shifting up 16 bytes, it shifts up 32 bytes, so 0x10000032 becomes 0x10000000.
Does anyone know how I can fix this?
Thank you!
Upvotes: 1
Views: 1692
Reputation: 9570
In C the expression ptr + ival
, where ptr
is a T*
pointer to the n-th item of an array of type T[]
and ival
is of integral type, is by definition a pointer to the (n+ival)
-th item of the same array (provided the resulting index falls inside the array length). So for
char b[7];
char *pb = &b[2];
char *qb = pb+3;
pointer qb
points at b[5]
, while for
long l[7];
long *pl = &l[2];
long *ql = pl+3;
pointer ql
points at l[5]
. Compiler automatically recognizes the actual size of byte
of long
items of an array, based on the pointer type.
Hence adding an integer value to a pointer corresponds to moving the pointer by the indicated number of elements (with the size of an element known by the type of a pointer), not by the given number of bytes in memory.
Similary, subtracting an integer value from a pointer value yields a pointer shifted a given number of items (not bytes) back.
Upvotes: 0
Reputation: 206587
Instead of using var1 + sizeof(structA)
use var1 + 1
Pointer arithmetic is defined such that the numerical value of the pointer is incremented (and decremented) by the size of the object type.
Hence, the numerical value of var1+1
is the same as the numerical value of var1
+ sizeof(*var1)
.
The numerical value of var1-1
is the same as the numerical value of var1
- sizeof(*var1)
.
Sample program
#include <stdio.h>
struct FiftyBytes
{
char d[50];
};
struct FortyBytes
{
char d[40];
};
void test1()
{
struct FiftyBytes a[2];
struct FiftyBytes* var1 = a;
struct FiftyBytes* var2 = var1 + 1;
printf("var1: %p, var2: %p\n", var1, var2);
struct FiftyBytes* var3 = &a[1];
struct FiftyBytes* var4 = var3 - 1;
printf("var3: %p, var4: %p\n", var3, var4);
}
void test2()
{
struct FortyBytes a[2];
struct FortyBytes* var1 = a;
struct FortyBytes* var2 = var1 + 1;
printf("var1: %p, var2: %p\n", var1, var2);
struct FortyBytes* var3 = &a[1];
struct FortyBytes* var4 = var3 - 1;
printf("var3: %p, var4: %p\n", var3, var4);
}
int main()
{
test1();
test2();
}
Output
var1: 0x22ca50, var2: 0x22ca82
var3: 0x22ca82, var4: 0x22ca50
var1: 0x22ca70, var2: 0x22ca98
var3: 0x22ca98, var4: 0x22ca70
If you check the differences in the pointer values, you'll notice that:
0x22ca82 - 0x22ca50 = 0x32 = 50
0x22ca98 - 0x22ca70 = 0x28 = 40
Upvotes: 6