問題タブ [pointer-arithmetic]

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 投票する
3 に答える
13501 参照

c - Cでの間接参照と括弧参照の操作の順序

私がそうする場合*ptr[x]、それは、、またはと同等*(ptr[x])ですか(*ptr)[x]

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

c++ - ポインターエイリアスの問題を解決するには?

テンプレートを不注意に使用すると、肥大化する可能性があります。その肥大化を回避する 1 つの方法は、タイプセーフではない非テンプレート コードをラップするシン タイプ セーフ テンプレートを使用することです。これを行うには、ラッパーは、テンプレート以外のコードが何も知らないものにアクセスするための何らかの方法を提供する必要があります。

たとえば、データ構造では、ラッパーはノード構造体を定義します。アンセーフ コードはノードの読み取りと書き込みを行う必要がありますが、ラッパーによって指定された何らかの種類のインターフェイスを介して間接的に行う必要があります。

このインターフェイスを実装する 1 つの方法は、ラッパーによって決定される関数ポインターや定数などの詳細を構造体 (アンセーフ コードによって定義される) に入力することです。関連する定数の 1 つに、特定のフィールドの (何らかの構造内の) オフセットがあります。アンセーフ コードは、そのオフセット (およびいくつかのポインター演算) を使用して、そのフィールドに直接アクセスできます。

ただし、これは問題になりつつあります。オプティマイザーがより積極的になると、ポインター エイリアスの問題が発生する可能性があります。これは、ノードがライブラリをエスケープできる場合に特に当てはまります。たとえば、ノードを二分木から抽出し、再リンクしてリンク リストを形成することができます。もう 1 つの例は、厄介なことに、単体テストのときに発生します。

私は現在、これらの方針に沿ってコンテナ ライブラリを作成していますが、現時点ではこれらの問題は発生していませんが、まもなく問題が発生する可能性があります。これらの問題を回避する理由は、すべての単体テストが (基になるコードではなく) コンテナーに適用され、ノードがコンテナーを決してエスケープしないためです。つまり、ノードは常に同じポインター演算方法でアクセスされるため、ポインター エイリアスの最適化の問題は発生しません。

残念ながら、コンテナからノードを抽出できるようにする必要がすぐに出てきます。おそらく、基になるアンセーフ コードの単体テストも必要になるでしょう。

この特定のライブラリを扱うのではなく、同じ問題を抱えている古いバイナリ ツリー ライブラリからのより単純な抜粋をここに示します。VC++9 では、それは機能します。MinGW GCC 4.4.0 を使用すると、デバッグ ビルドは機能しますが、リリース ビルドは失敗します。問題は、インライン化と、オプティマイザーがポインター エイリアスを見つけられないことが混在していることです。

はっきりさせておきますが、ここでは「WTF - GOTO!!!」は使いたくありません。または何でも。問題は、最適化/ポインターの問題を解決することです。ただし、適切に構造化され、それを達成するために隠し/偽装された goto を使用しない方法を見つけることができればTree_To_List、私は興味があります。

また、テンプレートベースの抽象化のレイヤーが欠落しています (テンプレート c_Bin_Tree_Tool はすべての仕事を行うわけではありません - c_Tool はラッピングを終了しますが、再利用可能な形式ではなく、使用ごとの方法で行います。これは単なる副作用です関連するコードを抽出します。

このコードが行うことは、ノードを 1 つずつ挿入して不均衡なバイナリ ツリーを作成し、そのツリーのバランスをとることです。バランシングは、ツリーをリストに変換し (ある意味では既にそうです)、リストをツリーに変換することによって機能します。ツリーはバランス調整の前後に stdio にダンプされます。

bintree.h...

test_bintree.cpp...

期待される結果は...

実際に何が起こるか (MinGW GCC 4.4.0、最適化されたリリース ビルド)...

私が知る限り、Balance 操作は正しく実行されますが、BT_Dump 関数はフィールドm_Leftm_Rightフィールドへのすべての変更を確認できません。

編集それは間違っています-そうでなければ、ノード1を新しいルートと見なすのはなぜですか。数か月前に行われた調査の記憶に頼りすぎると、それが起こると思います。

編集実際には、ルートとしてのノード 1 は問題ですが、それは古いルートだったので、この問題を無視して独自の理論を構築するのが最善です ;-)

コードには、標準が定義されていないという点で、多くの問題があります。最大の問題は、ノード構造体のリンクが c_Node* であることだと思いますが、安全でないコードは c_Node について何も知らないため、(ポインター演算を介して) void* としてそれらにアクセスします。

修正の 1 つは、アンセーフ コードが getter および setter 関数ポインターを介してすべての読み取りと書き込みを行い、すべてのポインター演算を回避し、c_Node インスタンスへのすべてのアクセスが c_Node* ポインターを介して行われるようにすることです。さらに良いことに、インターフェイスは getter/setter メソッドなどを持つクラスになります。完全なバイナリ ツリー ライブラリでは、これを行う別のポリシー クラスがあります。 「ジャンク」フォルダーは、私がめったに使用しないことに基づいており、おそらくブースト侵入リストを使用する必要があります。

ただし、これにより、他のはるかに複雑で頻繁に使用されるコンテナー ライブラリが残り、なくなることはありません。offsetof とポインター演算を取り除くために、非常に骨の折れるリファクタリングを行う必要があると思いますが、...

C++ の規則とは正確には何ですか? また、上記のバイナリ ツリー コードを書き直して、ポインタ演算を引き続き使用し、ライブラリの内部と外部の両方でノードにアクセス/変更できるようにし、さらにこの最適化の問題を回避できるようにすることはできますか?

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

c - ボイド・代入問題

ポインター演算を使用してパケット構造体からいくつかのフィールドを取得したいのですが、以下のコードの何が問題になっていますか?
最初の条件では、パケットの先頭から 4 バイト (2 つの短いフィールド) に移動すると tLow を取得すると思います。しかし、期待値が得られません。私の考えは間違っていますか?

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

c# - 新しいIntPtr.Addメソッド-intのポイントが欠落していますか?

FW 4.0以降、IntPtr構造には次のAddメソッドがあります。

IntPtrこれは、私たちが持っていた数学に関するすべての質問(1、2、おそらくそれ以上)に対処することになっているので、素晴らしいことです

しかし、なぜoffset intですか?
そうではないIntPtrでしょうか?範囲を超える値で64ビットポインタをオフセットすることは容易に想像できintます。


たとえば、次のことを考慮してMarshal.OffsetOfください。

IntPtr構造体メンバーへのオフセットとしてを返します。これは完全に理にかなっています!Addまた、このオフセットを新しい方法で簡単に使用することはできません。にキャストしてから、ループで数回Int64呼び出す必要があります。Add

IntPtr.Sizeまた、適切に作成されたアプリケーションとは無関係であるという考えそのものを殺しているようです。オフセットをなどの特定のタイプにキャストするInt64必要があります。その時点で、サイズの違いの管理を開始する必要があります。そして、128ビットIntPtrが表示されたときに何が起こるかを想像してください。


ここでの私の質問は、なぜですか?
私は結論を正しているのでしょうか、それとも要点を見逃しているのでしょうか。

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

c - Cのメモリアドレスによる人口構造

構造体のメンバーにアドレス参照を設定しているときに問題が発生しましたが、メンバーを使用して実行すると、それ自体で問題ありません。

構造部材付き

メモリアドレス付き

ここで、actual_data_lengthは変数のサイズであり、data_startはデータバッファーを指すポインターです。

メモリを使用すると、フィールドを印刷したときにガベージ値が返され、全体を実行した後、セグメンテーション違反が発生しますが、GDBでデバッグすると、プログラムは正常に終了しました。セグメンテーション違反はありませんでした。

提案してください

前もって感謝します

よろしく、Soheb

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

c - strchr の問題

次の C コードが機能しない理由がわかりません。

アイデアは、c1との間の文字数を見つけることc2です。

残念ながら、これは常に 1 と表示されます。何が問題なのですか? strchrC# のように動作するべきではありませんstring.IndexOf()か?

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

c - Cでの明らかなNULLポインター逆参照は、実際にはポインター演算ですか?

私はこのコードを持っています。ここではnullポインターを逆参照しているように見えますが、結果をビット単位でAND演算しunsigned intます。私は本当に全体を理解していません。それは何をするつもりですか?これはポインタ演算の形式ですか?

私が得る出力は44です。しかし、それはどのように機能しますか?

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

c - 定数ポインタ配列または配列へのポインタ? Cで何が速いですか?

こんにちは、私は現在中間 C クラスにいますが、この考えが頭に浮かびました。

では、多次元配列の位置にアクセスするために、より速く/より小さく/最適化されたものは何ですか?

これ:

また

または(更新)

"multi" は const 配列であるため、コンパイラは要素位置のローカリゼーションを既に "知っている" 必要があります。表示したいアイテム。より速く/より小さく/最適化されたアプローチは何ですか?

前もって感謝します。

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

visual-c++ - uintptr_t ポータブル代替

ある種のメモリ アラインメントのチェックを実行したいT。これを行う簡単な方法は次のとおりです。

ただし、uintptr_t既存の C++ 標準の一部ではなく、一部のコンパイラではサポートされていないため、これを行う移植可能な代替方法を探しておりstd::ptrdiff_t、私にとっては良さそうです。std::ptrdiff_t2 つのポインターの違いを格納できることが保証されていますが、これらのポインターの 1 つが null ポインターになることはできないと誰が言いますか? その場合std::ptrdiff_t、ポインタ自体と少なくとも同じサイズである必要があります。

またはそのように( による乗算を取り除くためsizeof(T)

このような解決策についてどう思いますか。携帯性は十分ですか?これが失敗する理由はわかりませんが、確認したいと思います。

ありがとう。

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

c - ポインタ演算の明確化

a * sizeがアドレス(p)に追加される場合、なぜb * sizeが*(p + a)に追加されるのですか?*(p + a)はその場所の値のようであり、それにb * sizeを追加すると、アドレスではなくその値が変更されます。しかし、私が読んだことに基づいて、これはアドレスに追加されることを意味します。