例:
sizeof(char*)
4を返します。、と同様int*
にlong long*
、私が試したすべてのものです。これに例外はありますか?
例:
sizeof(char*)
4を返します。、と同様int*
にlong long*
、私が試したすべてのものです。これに例外はありますか?
回答:
あなたが得る保証はそれsizeof(char) == 1
です。それ以外の保証はありませんsizeof(int *) == sizeof(double *)
。
実際には、ポインタは、16ビットシステム(サイズがある場合)でサイズ2、32ビットシステムで4、64ビットシステムで8になりますが、特定の値に依存しても何も得られません。サイズ。
単純なx86 32ビットプラットフォームでも、さまざまなポインターサイズを取得できます。例としてこれを試してください。
struct A {};
struct B : virtual public A {};
struct C {};
struct D : public A, public C {};
int main()
{
cout << "A:" << sizeof(void (A::*)()) << endl;
cout << "B:" << sizeof(void (B::*)()) << endl;
cout << "D:" << sizeof(void (D::*)()) << endl;
}
Visual C ++ 2008では、members-to-member-functionのサイズとして4、12、8が表示されます。
既に投稿されたリストのもう1つの例外です。32ビットプラットフォームでは、ポインタは4バイトではなく 6 バイトを使用できます。
#include <stdio.h>
#include <stdlib.h>
int main() {
char far* ptr; // note that this is a far pointer
printf( "%d\n", sizeof( ptr));
return EXIT_SUCCESS;
}
このプログラムをOpen Watcomでコンパイルして実行すると、6になります。これは、サポートするfarポインターが32ビットのオフセットと16ビットのセグメント値で構成されるためです。
64ビットマシン用にコンパイルしている場合は、8になる可能性があります。
sizeof(char*)==1
? 本気ですか?どういう意味size(char)==1
ですか?
技術的に言えば、C標準はsizeof(char)== 1のみを保証し、残りは実装次第です。しかし、最新のx86アーキテクチャ(例:Intel / AMDチップ)では、かなり予測可能です。
16ビット、32ビット、64ビットなどとして説明されているプロセッサを聞いたことがあるでしょう。これは通常、プロセッサが整数にNビットを使用することを意味します。ポインタはメモリアドレスを格納し、メモリアドレスは整数であるため、ポインタに使用されるビット数が効果的にわかります。sizeofは通常バイト単位で測定されるため、32ビットプロセッサ用にコンパイルされたコードはポインタのサイズを4(32ビット/バイトあたり8ビット)と報告し、64ビットプロセッサのコードはポインタのサイズを8と報告します(64ビット/バイトあたり8ビット)。これは、32ビットプロセッサの4 GBのRAMの制限が原因です。各メモリアドレスがバイトに対応している場合、より多くのメモリをアドレス指定するには、32ビットより大きい整数が必要です。
ポインターのサイズは、基本的には、ポインターが実装されているシステムのアーキテクチャーに依存します。たとえば、32ビットのポインターのサイズは、64ビットマシンでは4バイト(32ビット)および8バイト(64ビット)です。マシンのビットタイプは、それが持つことができるメモリアドレスにすぎません。32ビットマシンは2^32
アドレススペースを持つことができ、64ビットマシンは最大2^64
アドレススペースを持つことができます。したがって、ポインタ(メモリの場所を指す変数2^32 for 32 bit and 2^64 for 64 bit
)は、マシンが保持するメモリアドレス()のいずれかを指すことができる必要があります。
このため、ポインターのサイズは32ビットマシンでは4バイト、64ビットマシンでは8バイトです。
16/32/64ビットの違いに加えて、さらに奇妙なことが発生する可能性があります。
sizeof(int *)が1つの値(おそらく4)になるマシンがありますが、sizeof(char *)の方が大きいマシンがあります。バイトではなくワードを自然にアドレス指定するマシンは、C / C ++標準を適切に実装するために、実際に必要なワードの部分を指定するために文字ポインターを「拡張」する必要があります。
ハードウェアの設計者がバイトアドレス指定の価値を学んだため、これは今では非常に珍しいことです。
void*
およびchar*
ソフトウェアで処理され、ワード内に3ビットのオフセットが追加されます。ただし、実際には64ビットのアドレス空間がないため、オフセットは64ビットの上位3ビットに格納されます。語。したがってchar*
、int*
サイズは同じですが、内部表現が異なります。また、ポインタが「実際に」だけであると想定しているコードでは、整数は正しく機能しない可能性があります。
人々が64ビット(または何でも)システムについて言ったことに加えて、オブジェクトへのポインター以外の種類のポインターがあります。
メンバーへのポインターは、コンパイラーによる実装方法に応じて、ほぼすべてのサイズになる可能性があります。必ずしもすべて同じサイズである必要はありません。PODクラスのメンバーへのポインターを試してから、複数の基底を持つクラスの基本クラスの1つから継承されたメンバーへのポインターを試してください。なんて楽しい。
私が覚えていることから、それはメモリアドレスのサイズに基づいています。したがって、32ビットアドレス方式のシステムでは、sizeofは4バイトなので、4を返します。
sizeof (unsigned int) == sizeof (signed int)
、この要件は3.9.1 / 3にあります。「タイプの符号付き整数標準の各々について、対応する(しかし異なる)標準の符号なし整数型が存在する:unsigned char
、unsigned short int
、unsigned int
、unsigned long int
、及びunsigned long long int
、ストレージの同じ量を占有し、対応する符号付き整数型と同じアライメント要件をそれぞれ有します "
Windows 32ビットマシンのTurbo Cコンパイラでは、ポインタとintのサイズは2バイトです。
したがって、ポインタのサイズはコンパイラ固有です。しかし、一般的にほとんどのコンパイラーは、32ビットの4バイトのポインター変数と64ビットのマシンの8バイトのポインター変数をサポートするように実装されています。
したがって、ポインタのサイズはすべてのマシンで同じではありません。
ポインタのサイズが4バイトである理由は、32ビットアーキテクチャ用にコンパイルしているためです。FryGuyが指摘したように、64ビットアーキテクチャでは8と表示されます。
ではWin64の(CygwinのGCC 5.4) 、のは、以下の例を見てみましょう:
まず、次の構造体をテストします。
struct list_node{
int a;
list_node* prev;
list_node* next;
};
struct test_struc{
char a, b;
};
テストコードは次のとおりです。
std::cout<<"sizeof(int): "<<sizeof(int)<<std::endl;
std::cout<<"sizeof(int*): "<<sizeof(int*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(double): "<<sizeof(double)<<std::endl;
std::cout<<"sizeof(double*): "<<sizeof(double*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(list_node): "<<sizeof(list_node)<<std::endl;
std::cout<<"sizeof(list_node*): "<<sizeof(list_node*)<<std::endl;
std::cout<<std::endl;
std::cout<<"sizeof(test_struc): "<<sizeof(test_struc)<<std::endl;
std::cout<<"sizeof(test_struc*): "<<sizeof(test_struc*)<<std::endl;
出力は以下のとおりです。
sizeof(int): 4
sizeof(int*): 8
sizeof(double): 8
sizeof(double*): 8
sizeof(list_node): 24
sizeof(list_node*): 8
sizeof(test_struc): 2
sizeof(test_struc*): 8
あなたは64ビットで、ことがわかりますsizeof(pointer)
です8
。
ポインターはアドレスのコンテナーにすぎません。32ビットマシンでは、アドレス範囲は32ビットなので、ポインターは常に4バイトになります。64ビットマシンでは、アドレス範囲が64ビットの場合、ポインターは8バイトになります。
完全性と歴史的な関心のために、64ビットの世界では、主にUnixタイプのシステムとWindowsの間で、LLP64とLP64という名前のlong型とlong long型のサイズに異なるプラットフォーム規則がありました。ILP64という名前の古い規格もint = 64ビット幅にしました。
マイクロソフトは、移植を容易にするために、longlong = 64ビット幅のLLP64を維持しましたが、longは32のままでした。
Type ILP64 LP64 LLP64
char 8 8 8
short 16 16 16
int 64 32 32
long 64 64 32
long long 64 64 64
pointer 64 64 64