C arithmetic void pointer

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

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

really returns 0x984a008 0x984a009. Similarly, void ** points to a pointer, so incrementing by one really means incrementing by 4 bytes (in 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 he is returning again 0x984a008 0x984a009. What's going on here?

+5
source share
5 answers

Ignoring the possible behavior of undefined pointer arithmetic voidat the moment ...

Type p1- void *.

, . p1 void *.

void * ( , ).

, , .

EDIT:

, , - .

- , , : (-)

  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
+7

char * void *, void gcc.

char *p1 = /* ... */;

printf("%p %p\n", p1, p1+1);

p p char * ( char **).

:

char *p1 = /* ... */;

printf("%p %p\n", p1, (char**)p1+1);

char **.

+3

void *, 1. void **, .

, , void * void ** void *. :

long a, b, c;
c = a + (int) b;

b int, long, .

+2

void . undefined.

: void ? ?

+1

, , , .

I agree with @Dukeling that you cannot change the type of a variable just by dropping it. But it looks like it depends on what the compiler thinks void. Take this sample program and look at the result. Note that the only difference between vpand vp2is part sizeof() malloc().

Compiled: gcc (Debian 4.7.2-5) 4.7.2
Compilation Line:gcc -o void_test void_test.c

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  void *vp, *vp2;

  printf("sizeof(void)   = %d\n", sizeof(void));
  printf("sizeof(void *) = %d\n", sizeof(void *));
  printf("sizeof(char)   = %d\n", sizeof(char));
  printf("sizeof(char *) = %d\n\n", sizeof(char *));

  vp = (void *) malloc(sizeof(void));
  vp2 = (void *) malloc(sizeof(void *));

  printf("vp    = %p\n", vp);
  printf("vp+1  = %p\n", vp+1);
  printf("vp2   = %p\n", vp);
  printf("vp2+1 = %p\n", vp2+1);

  return 0;
}

It gives the following result:

$ ./void_test 
sizeof(void)   = 1
sizeof(void *) = 8
sizeof(char)   = 1
sizeof(char *) = 8

vp    = 0x1ee3010
vp+1  = 0x1ee3011
vp2   = 0x1ee3010
vp2+1 = 0x1ee3031
0
source

All Articles