Mo Jo
Mo Jo

Reputation: 11

Pointer arithmetic in C adding and subtracting wrong

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

Answers (3)

CiaPan
CiaPan

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

R Sahu
R Sahu

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

jayant
jayant

Reputation: 2389

You can do the following

((char*)var1) + sizeof(structA)

Upvotes: 1

Related Questions