5

gcc では、void * と char * はポインター演算に関しては同じように扱われる、つまり void * はメモリ内の 1 バイトを「指す」と考えたので、次のコードは

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

確かに戻ります0x984a008 0x984a009。同様に、void ** はポインターを指すため、1 ずつインクリメントすると実際には (32 ビット OS では) 4 バイトずつインクリメントされます。つまり、

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

戻ります0x984a008 0x984a00c。ただし、次のコードは私を混乱させます

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

また 戻る から0x984a008 0x984a009. ここで何が起こっているのですか?

4

5 に答える 5

7

void現時点では、ポインター演算の未定義の動作の可能性を無視しています...

の型はp1ですvoid *

別の型の値を代入して変数の型を変更することはできません。p1常に滞在しvoid *ます。

それに代入された別の型の式は、暗黙的にキャストされますvoid *(キャストできない場合はエラーが発生します)。

したがって、基本的には最初の例と同じです。

編集:

私の知る限り、あるポインター型から別のポインター型へのキャストは実際には何もしません。その主な目的は型チェックです。

ポインターは単なるメモリアドレス、つまり数値であるため、基本的にメモリは次のようになります: (割り当て後)

  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
于 2013-03-05T16:29:26.157 に答える
3

ポインタの演算は gcc 拡張であるため、char *代わりに を使用する必要があります。void *void

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

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

ポイントが何であれp、ポインタ算術pchar *type (not char **) を使用します。

あなたが書く場合:

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

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

ポインター演算は を使用しchar **ます。

于 2013-03-05T16:30:21.830 に答える
2

で操作する場合void *、増分は 1 です。使用する場合void **は、ポインタのサイズです。

あなたを混乱させる操作では、void *へのキャストvoid **が暗黙的に に戻されていvoid *ます。あなたがこれをしたかのようです:

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

にキャストbしましたintが、 で操作したいlongので、キャストバックされます。

于 2013-03-05T16:28:05.737 に答える
1

void ポインタはインクリメントできません。これは未定義の動作です。

関連する質問: void ポインターを 1 バイトずつ増やしますか? 二人で?

于 2013-03-05T16:25:37.207 に答える
0

1年以上後に投稿していることは知っていますが、たまたまこの質問に出会い、興味をそそられました。

キャストするだけでは変数の型を変更できないという@Dukelingに同意します。しかし、それはコンパイラが何と見なすかに依存しているvoidようです。このサンプル プログラムを使用して、結果の出力を見てください。vpとの唯一の違いvp2は のsizeof()部分であることに注意してくださいmalloc()

コンパイル日:gcc (Debian 4.7.2-5) 4.7.2
コンパイル行: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;
}

次の出力が得られます。

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

vp    = 0x1ee3010
vp+1  = 0x1ee3011
vp2   = 0x1ee3010
vp2+1 = 0x1ee3031
于 2014-06-27T14:24:52.543 に答える