問題タブ [memory-alignment]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
5 に答える
6218 参照

c - スタックの割り当てと配置を理解する

「スタックアラインメント」とは何かで説明されているように、スタックアラインメントがどのように機能するかを理解しようとしていますか?しかし、私は前述の振る舞いを示すための小さな例を得るのに苦労しています。関数fooのスタック割り当てを調べています。

ソースファイルをコンパイルしましたgcc -ggdb example.c -o example.out(つまり、コンパイラフラグなしで)。gdbからのアセンブラダンプは次のようになります。

私のスタックは16バイトのチャンクに割り当てられています(これを他のいくつかのテストで検証しました)。ここでのアセンブラダンプによると、(16 <4 + 16 <32)のため、32バイトが割り当てられていますが、最初の16バイトに整数'a'が割り当てられ、次の16バイトに文字配列が割り当てられると予想しました。 (間に12バイトのスペースを残します)。しかし、整数配列と文字配列の両方に20バイトの連続したチャンクが割り当てられているようです。これは、上記で説明したように非効率的です。誰かが私がここで欠けているものを説明できますか?

編集:私は私のスタックが以下のようなプログラムで16バイトのチャンクに割り当てられているという結論に達しました:

そして、対応するアセンブラダンプ:

サイズ1の文字配列(1バイトのみが必要)のスタックに16バイトが割り当てられていることがわかります。配列のサイズを最大16まで増やすことができ、アセンブラーダンプは同じままですが、17の場合、スタックに32バイトが割り当てられます。私はそのようなサンプルをたくさん実行しましたが、結果は同じです。スタックメモリは16バイトのチャンクで割り当てられます。同様のトピックがスタックの割り当て、パディング、および配置で説明されていますが、私がもっと知りたいのは、私の例では配置が効果がない理由です。

0 投票する
3 に答える
4163 参照

c - GCC の暗黙のアラインメントの問題。(64ビットコード)

gccで定義された変数のアライメントを明示的に無効にするにはどうすればよいですか?
次のコードを使用します。

これにより、サイズが 24 バイトの構造が定義されます。
私はやってみました:

したがって

&memstrx[0]、値は 0x502
&memstrx[1]、 0x51A
&memstrx[2]、 0x532

... などになります。

しかし、物事は正しくないようです。

代わりに、は 0x522 、 0x542 、 0x552

&memstrx[1]のアドレスを表示します
&memstrx[2]
&memstrx[3]

...などなど。

GCC が暗黙のうちに構造体のサイズを (24 バイトから) 32 バイトに変更し、(各エントリの 64 ビット アラインメント) を強制したのではないかと思います。そして、この構造だけでこの動作が必要なわけではありません。その構造を整列させないようにGCCにどのように指示すればよいですか?

0 投票する
8 に答える
13423 参照

c++ - C ++の原子性:神話または現実

私はMSDNのロックレスプログラミングに関する記事を読んでいます。それは言う:

最近のすべてのプロセッサでは、自然に整列されたネイティブタイプの読み取りと書き込みはアトミックであると想定できます 。メモリバスが少なくとも読み取りまたは書き込み中のタイプと同じ幅である限り、CPUはこれらのタイプを単一のバストランザクションで読み取りおよび書き込みし、他のスレッドがそれらを半分完了した状態で見ることを不可能にします。

そしてそれはいくつかの例を与えます:

私はたくさんの回答とコメントを読んで、C ++でアトミックであることが保証されているものはなく、標準でも言及されていないので、SOでは少し混乱しています。私は記事を誤解していますか?それとも、記事の執筆者は、非標準でMSVC ++コンパイラに固有のものについて話しますか?

したがって、記事によると、以下の割り当てはアトミックでなければなりませんよね?

それが本当の場合、置換Name[5]と置換はメモリアライメントに違いをもたらしますかpad3[3]std::string Name;変数への割り当てNumber2Value変数は引き続きアトミックですか?

誰か説明してもらえますか?

0 投票する
3 に答える
2275 参照

c++ - std::map ノードの配置

私は非常に驚くべきことに直面しています。(シナリオ: Win7 pro 64 ビット、VC2008 コンパイル 32 ビット コード)

メイン プログラムが std::map を使用するクラスをインスタンス化するとします。
これは std::map<std::string,Props> であり、クラス Props には 2 つのメンバーしかありません。

今...私はDLLを構築し、同じクラスを独自のビジネスに使用しています。
DLL はそのクラスをインスタンス化し、std::map をフィードします。

ええと...メインプログラムがマップにフィードすると、すべてがうまくいきますが、最初のアイテムの挿入後にDLLがクラッシュします。

何か(非常に興味深い)もっと。
メイン プログラムによって行われた挿入を深く掘り下げると、単一の _Node のコンストラクターに到達して std::map
_Node に次のように表示されます (c:\Programmi\Microsoft Visual Studio 9.0\VC\include\xtree)。

非常に細かい...つまり、_Node 構造は _Left (4 バイト)、_Parent (4 バイト)、_Right (4 バイト)、_Myval (キーのサイズとマップの値)、_Color (1 バイト)、および _Isnil (1 バイト) を持っています。
さて...マップにフィードしたい要素は、<std::string, Props> のペアです。
私のデバッガーによると、std::string には 0x20 バイトが必要ですが、Props は 8 バイトしか必要ありません。

ここで、デバッガーに単一ノードのサイズを尋ねると、0x38 であることがわかります。つまり...0x4 + 0x4 + 0x4 + 0x20 + 0x8 + 0x1 + 0x1 = 0x36 + パディング = 0x38 です。
これは、_Color メンバーが _Node の先頭から 0x34 バイト後に始まることを意味します。

(わかりました...すべてのプロジェクトで /Zp4 を使用するように指定したいので、すべての構造は 4 バイトでパックされます)。

続けてみましょう... DLL の動作をたどると、非常に驚​​くべきことがわかります。
std::map の _Buynode() メソッドは、アロケータを呼び出して、挿入しようとしている新しい要素の新しいサイズを取得します。_Node() インプレースコンストラクターが呼び出されるよりもアロケーターが呼び出されます....そして、別の方法で動作します!!

この場合、コンストラクターは、_Node の先頭から 0x38 バイトの後に _Color メンバーが開始するように動作します... あたかも別のパディングがあるかのように。
この後、新しい値を挿入しようとすると、_Color と _Isnil の値が間違っているため、手順は失敗します (メモリのその部分が初期化されていないため 0xcc)。

すべてのプロジェクトで /Zp4 をソリューションに設定したと確信しているので...
何が問題なのですか?
アラインメントに何か問題があると「感じ」ますが、何とも言えません...

前もって感謝します!


わかりました...さらに何かを追加します。
これは、c:\Programmi\Microsoft Visual Studio 9.0\VC\include\xtree の _Node 構造です。

ご覧のとおり、コンストラクターは非常に単純です。
前に言われたように、std::map を asf するときに、この構造体から使用されるメモリを調べます。
- _Left の場合は
4バイト - _Parent の場合は 4 バイト - _Right
の場合は 4 バイト
- _Myval の場合は 0x28 バイト (std::string の場合は 0x20、自分のクラスの場合は 8 です。確認したところ、alqays は 8 バイト
です) - _Color の場合は 1 バイト
- 1 _Isnil のバイト

ツリーの一番上 (つまり、一番左) に配置された新しい要素が作成されると、このコストラクタは、_Left、_Parent、_Right、_Myval を、初期化されていない 4 バイト分 (たとえば 0xcc で埋められている) よりも埋め、_Color と見なされるものを埋めます。および _Isnil 4 バイト先。
最もばかげたことは、std::map の他のメソッドがこれらの 4 バイトを「感じない」ことです。
これらは、デアサーションを引き起こす行です。

これは、_IsNil(_Ptr) のテストで _Isnil が 0xcc であることを検出するとエラーが発生するために発生します。リリース バージョンはおそらくおかしくありません。これは喜ばしいことではありません。

何か案が?


もう一歩!
ソリューション全体 (2 つの大きなプロジェクト、18 の小さなプロジェクト、約 250000 の C/C++ コード行) を取り、Linux (gcc4.1.2) でコンパイルしました。
すべてうまくいきます。何の問題もなく、std::map は適切に動作します。
Linux Makefile は、すべてをより簡単にすると同時に複雑にすると言わざるを得ません。自分ですべてを行わなければならないので複雑ですが、したくない場合は何も起こらないので簡単です。

これは私に 1 つのことを教えてくれます: Visual Studio 2008 には何か問題があり、特定の条件でステージ上でジャンプする何かがあります...問題は、「これを引き起こす条件は何ですか?」です。

アイデアを待っています...

0 投票する
2 に答える
2001 参照

visual-c++ - ビジュアル C++ での型のデフォルトの配置

私には奇妙に見える何かに気づきました。Visual C++ は、既定ではオブジェクトを必要な境界に揃えません。たとえば、long long は 4 バイト境界に整列されますが、__alignof(T) は 8 を返します (私が見る限り、常に型のサイズを返します)。そのため、正しく配置されていないように見えます。例えば

また、ポインターを印刷しようとしました。値&a20x0035F8FC353714810進数)です。

何か間違っていますか?long long 型の適切に配置されたオブジェクトが必要です。それについて私は何ができますか?Microsoft の拡張機能を使用することもできます__declspec(align())が、リテラル番号が必要なので、そのようなものを書くことはできません。

0 投票する
4 に答える
655 参照

c - 構造を単語に合わせる必要があるのはなぜですか?

重複の可能性:
メモリアライメントの目的

構造体またはint、charなどのメモリ割り当てを単語に揃える必要があるのはなぜですか。それはどのような利点をもたらしますか?

更新:主な理由は、メモリアラインされていない場合、データ型(int)の一部が1つの物理ページにあり、他の部分が別の物理ページにある可能性があるためですか?

これがより強い理由だと思いますか?

0 投票する
6 に答える
615 参照

c++ - 特定のデータ型のバイト アライメント要件は、2 の累乗であることが保証されていますか?

特定のデータ型のバイト アライメント要件は、2 の累乗であることが保証されていますか?

システムページサイズと一致しないため、「そうでなければ意味がない」以外に、この保証を提供するものはありますか?

(背景: C/C++ であるため、データ型が C または C++ 型であると仮定して、C/C++ 固有の回答を提供してください。)

0 投票する
4 に答える
3924 参照

c++ - SSE および C++ コンテナー

次のコードが segfaults になる明白な理由はありますか?

ありがとう

編集: Linux/i686 で g++ 4.5.0 を使用しています。ここで何をしているのかわからないかもしれませんが、次の segfaults でさえ

私はそれがアライメントの問題であるに違いないと本当に思います。

0 投票する
3 に答える
6104 参照

java - Java メモリ割り当ての調整

Java でこれを尋ねるのは奇妙な質問だと思いますが、Java の動的メモリ割り当てをいくつかの配置制約に合わせる方法はありますか? たとえば、ページ サイズに合わせてオブジェクトを動的に割り当てることは可能ですか?

これを行う理由は、JNI インターフェイスを介してネイティブ コードから Java オブジェクトにアクセスするためであり、ネイティブ コード ライブラリではオブジェクトを整列させる必要があります。

ありがとう。

0 投票する
1 に答える
1821 参照

c++ - Referencing static object - alignment trap triggered on ARM proc

I have a class:

I am running this on an ARM processor. The issue I am encountering is that the application is triggering an alignment trap in the kernel when I call the instance() method from a particular class (say class B). If I call instance() from anywhere else, I do not encounter the alignment trap.

Alignment trap: not handling instruction e28fc609 at [<0001b588>]

I can see how this would happen if I were casting pointers to mis-aligned values, but I am simply referencing a static object. One would assume that the access would be correctly aligned.

Note the class is grossly simplified. It contains a lot of member variables and methods (not my design!).

Does anyone have any suggestions on where I may be going wrong, or where to look?