持つ
any_type *ptr = (any_type*)malloc(sizeof(any_type)*size);
my_ptr = ptr+1;
memcpy(dst, my_ptr, sizeof(any_type));
my_ptr は、ptr の後の 1 バイトを指しますか、それとも ptr の後のバイトを指しsizeof(any_type)
ますか? 配置オプションが答えにどのように影響するか? 署名された/署名されていないタイプでは異なりますか?
持つ
any_type *ptr = (any_type*)malloc(sizeof(any_type)*size);
my_ptr = ptr+1;
memcpy(dst, my_ptr, sizeof(any_type));
my_ptr は、ptr の後の 1 バイトを指しますか、それとも ptr の後のバイトを指しsizeof(any_type)
ますか? 配置オプションが答えにどのように影響するか? 署名された/署名されていないタイプでは異なりますか?
ポインター演算は、ポインターの静的型 [*] のサイズに対して実行されるため、実質的にsizeof *ptr
. メンバーの位置合わせは、型の位置合わせ (オブジェクトの末尾のパディング) として、オブジェクトのサイズで考慮されます。
struct test {
int a;
char b;
};
型が 4 バイトでアラインされている場合、のサイズはtest
5 にはなりません (32 ビット整数を想定)。
[*] C++ では、派生オブジェクトのアドレスを基底クラスに割り当てることができますが、ポインター演算は実際のオブジェクトではなく、ポインターの型で動作することに注意してください。
struct base { int x; };
struct derived : base { int y; };
int main() {
base * p = new derived[10];
base * q = p+1; // this does not point to the second `derived`!!!
}
コンパイラは、その 1 を適切なバイト数に置き換えます。移動先のオブジェクトの数を指定するだけです。
ポインターが表示されたら、それがスカラー値であることを忘れるようにしてください。代わりに、ポインタは、連続空間 (メモリ) に格納されているオブジェクトへのアクセスを提供する一種のトークンであると考えてください。Ifptr
は、ある (任意の) 位置にあるオブジェクトへのアクセスを提供するポインターでptr+1
ありptr-1
、近隣オブジェクトへのアクセスを提供するポインターを返します。
ポインター演算が機能するには、sizeof(any_type) + ベースアドレスを指す必要があります。