3

ビット操作に関連する以前の質問で、配列がアドレスと整列していない場合、ポインターを使用してchar配列にアクセスするコード(一度に大きなバイトのチャンクを操作するため) に問題がある可能性があると言われました。intcharint

次に、C で考えてmalloc、未知の型にメモリを割り当てるとどうなるのだろうと考えました。たとえば、void *p = malloc(sizeof(int));そうすると、有効な char/int/long-aligned メモリ アドレスを取得できますか?

ここで標準を引用するSOのいくつかの回答によると、「返されたポインターは、完全なオブジェクト型のポインターに変換できるように適切に配置される必要があります」。

したがって、この場合は問題なくからchar*に移動できることを理解しています。int*

char *p = malloc(16);
int *n = (int*)p; // use n a base of an array of 16 / sizeof(int) ints

それが正しいか?

C++ に移ると、同様のルールが標準に表示されているようです。では、これを行えばアラインメントのリスクはないと考えていいのでしょうか?

char *p = new char[16];
int *n = reinterpret_cast<int*>(p);
4

3 に答える 3

6

はい、mallocC と C++ および C++ の両方で、new char[N]最大限にアラインされたポインターを返します。位置合わせは、 または からのタイプの位置合わせですmax_align_t

gcc-4.8 にはこの点に関するバグがあり、gcc-4.9 で修正されています。プレフィックス::maxalign_tなしでインクルードして使用するだけです。std::

オーバーアラインされた型、つまりアラインメントが上記の最大値よりも大きい型のサポートは、実装によって定義されます。たとえば、Posix はposix_memalign、はるかに優れたアラインメント (ページ アラインメントなど) でメモリを割り当てることを提案しています。

于 2013-09-09T08:58:50.807 に答える
1
char* p = new char[16];
int* n = reinterpret_cast<int*>(p);

これでも問題ありませんが、さらに優れているのは次のとおりです。

char* p = new char[16];
int* n = static_cast<int*>(static_cast<void*>(p));

または、次のように C++ を使用することもできますoperator new

void* p = operator new(16);
int* n = static_cast<int*>(p);

1つ少なくなりstatic_castます。

于 2013-09-09T09:06:31.827 に答える
0

mallocC の任意の基本型に対して正しく配置されたアドレスを返します。つまり、これらすべての型 ( int、long など) のポインターに安全にキャストできることを意味しますdouble

于 2013-09-09T08:59:00.497 に答える