80

このステートメントは何をもたらすでしょうか?

void *p = malloc(sizeof(void));

編集:質問の延長。

GCC コンパイラで sizeof(void) が 1 を返す場合、1 バイトのメモリが割り当てられ、ポインタ p はそのバイトを指し、p++ は 0x2346 にインクリメントされますか? p が 0x2345 であるとします。*p ではなく、p について話しているのです。

4

10 に答える 10

62

タイプvoidにはサイズがありません。それはコンパイルエラーになります。同じ理由で、次のようなことはできません。

void n;

編集。驚いたことに、sizeof(void)実際に実行するとGNUCでコンパイルされます。

$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc -w - && ./a.out 
1

ただし、C ++では、次のことは行いません。

$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc++ -w - && ./a.out 
<stdin>: In function 'int main()':
<stdin>:1: error: invalid application of 'sizeof' to a void type
<stdin>:1: error: 'printf' was not declared in this scope
于 2009-11-03T09:31:42.357 に答える
43

GCCを使用していて、コンパイラ固有の拡張機能を削除するコンパイルフラグを使用していない場合は、sizeof(void)1です。GCCには、それを行う非標準の拡張機能があります。

一般に、voidは不完全な型であり、不完全な型にsizeofを使用することはできません。

于 2009-11-03T09:35:35.800 に答える
16

voidタイプの代わりになる場合もありますが、実際には値を保持できません。したがって、メモリ内にサイズはありません。aのサイズを取得することvoidは定義されていません。

void ポインタは、型指定されていないメモリへのポインタを意味する単なる言語構造です。

于 2009-11-03T09:33:44.337 に答える
11

void のサイズを取得するのはGCC の拡張機能です。

于 2009-11-03T09:39:02.043 に答える
6

sizeof()不完全なタイプには適用できません。そしてvoid、完成できない不完全なタイプです。

于 2009-11-03T09:34:13.147 に答える
3

Cではsizeof(void) == 1GCCですが、これはコンパイラに依存しているようです。

C ++では、次のようになります。

関数'intmain()':
2行目:エラー:void型への「sizeof」の無効な適用
-Wfatal-errorsが原因でコンパイルが終了しました。
于 2009-11-03T09:33:27.937 に答える
0

質問の2番目の部分:sizeof(void *)!= sizeof(void)に注意してください。32ビットアーチでは、sizeof(void *)は4バイトであるため、それに応じてp ++が設定されます。ポインターがインクリメントされる量は、ポインターが指しているデータによって異なります。したがって、1バイト増加します。

于 2009-11-03T09:57:19.360 に答える
-1

ほとんどの C++ コンパイラは、取得しようとしたときにコンパイル エラーを発生させることを選択しましたsizeof(void)

C をコンパイルするとき、gcc は適合せずsizeof(void)、1 として定義することを選択しました。奇妙に見えるかもしれませんが、理論的根拠があります。ポインター演算を行う場合、1 つの単位を追加または削除することは、サイズを指すオブジェクトを追加または削除することを意味します。したがって、1 として定義すると、バイト (型指定されていないメモリ アドレス) へのポインターとしてsizeof(void)定義するのに役立ちます。void*そうしないと、p+1 == p whenp isのようなポインター演算を使用して驚くべき動作をすることになりますvoid*。このような void ポインターでのポインター演算は、c++ では許可されていませんが、gcc で C をコンパイルする場合は正常に機能します。

標準的に推奨される方法はchar*、そのような目的 (バイトへのポインター) に使用することです。

sizeof を使用する場合の C と C++ の別の同様の違いは、次のような空の構造体を定義したときに発生します。

struct Empty {
} empty;

C コンパイラとして gcc を使用sizeof(empty)すると 0 が返されます。g++ を使用すると、同じコードは 1 を返します。

この点で C と C++ の両方の標準が何を示しているかはわかりませんが、いくつかの空の構造体/オブジェクトのサイズを定義すると、参照管理で、異なる連続したオブジェクトへの 2 つの参照 (最初の参照が空) を回避するのに役立つと思います。同じ住所。参照がよく行われるように隠しポインタを使用して実装されている場合、異なるアドレスを確保するとそれらを比較するのに役立ちます。

しかし、これは、別の動作 (空のオブジェクト、POD でさえ少なくとも 1 バイトのメモリを消費する) を導入することによって、驚くべき動作 (参照のコーナー ケースの比較) を回避するだけです。

于 2013-03-21T09:34:36.400 に答える
-2

sizeof(void) 自体は意味をなさないかもしれませんが、ポインタ演算を行う場合は重要です。

例えば。

 void *p;
 while(...)
      p++;

sizeof(void) が 1 と見なされる場合、これは機能します。sizeof(void) が 0 と見なされると、無限ループに陥ります。

于 2011-11-17T19:59:03.910 に答える