Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C void pointer arithmetic

Tags:

c

pointers

I thought that in gcc, void * and char * are treated the same way when it comes to pointer arithmetic, i.e. void * "points" to a single byte in memory, so the following code

void *p;
p = malloc(sizeof(void));
printf("%p %p\n",p,p+1);

indeed returns 0x984a008 0x984a009. Similarly, void ** points to a pointer, so an increment by one really means an increment by 4 bytes (on a 32 bit OS), i.e.

void **p;
p = (void **) malloc(sizeof(void *));
printf("%p %p\n",p,p+1);

returns 0x984a008 0x984a00c. However, the following code confuses me

void **p, *p1;
p = (void **) malloc(sizeof(void *));
p1 = (void **) p;
printf("%p %p\n",p1,p1+1);

Since it returns again 0x984a008 0x984a009. What is going on here?

like image 368
Ivan Avatar asked Mar 05 '13 16:03

Ivan


1 Answers

Ignoring the possible undefined behaviour of void pointer arithmetic for the moment...

The type of p1 is void *.

You can't change a variable's type by assigning a value of a different type to it. p1 will always stay void *.

Any expression of a different type assigned to it will implicitly be cast to void * (or give an error if it can not).

Thus it's essentially the same as the first example.

EDIT:

As far as I know, casting from one pointer type to another doesn't actually do anything, its main purpose is for type-checking.

A pointer is just a memory address, a number, so essentially the memory looks something like: (post-assignment)

  p1       p2
void *   void** <- these types are fixed and known during compilation
------   ------
|1234|   |1234|         at address 1234 = the 4 bytes from malloc
------   ------
  ^
  |
this value is the only thing that will change by assigning p1 to a different value
like image 64
Bernhard Barker Avatar answered Sep 30 '22 02:09

Bernhard Barker