問題タブ [placement-new]
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.
c++ - テンプレート化された関数と配置の新しいコンストラクタ パラメータ
メモリ マネージャー クラスで宣言されたテンプレート化されたメソッドがいくつかあります。
アイデアは、メソッドがメモリを割り当て、指定されたクラスのコンストラクターを呼び出すということです。
問題は、コンストラクターの引数を指定する場合です。私が持っている唯一の解決策は、バリエーションごとに関数をオーバーロードする場所の上にあります。私はそれが非常に実行可能だとは思いません。
より良い解決策はありますか?
c++ - 潜在的にplacement newを使用しながら配列を作成する方法
私は楽しい演習/練習としてカスタム アロケーターの作成に取り組んできましたが、配列の作成に関して 2 つの潜在的な問題に遭遇しました。割り当ての典型的な呼び出しでは、 と を使用malloc
しplacement new
ます。ただし、配列を作成しようとすると、どのように行うべきか混乱しています。ここで、 hereplacement new
のような配列に対して安全ではない可能性があることに気付きました。また、配列に使用しようとしているときに、自分自身のエラーが発生しています。のエラーが発生しますplacement new
「エラー C2679: バイナリ '=' : 'SomeClass *' 型の右側のオペランドを取る演算子が見つかりません (または、受け入れ可能な変換がありません)
私はエラーを理解しています(私は信じています)が、配列構築方法でエラーを解決したいと思っています。2つの質問があります
1) アロケータは、どのように使用せずに配列を作成できますnew[]
か? と一緒placement new
ですか?もしそうなら、私が上に投稿したリンクから言及された潜在的な危険性はどうですか?
2)placement new
配列内の各要素に対してそれを使用して呼び出すとしたら、なぜ上記のエラーが発生するのですか?
c++ - 新しい配置はメモリをゼロにしますか?
私は次のコードを持っています:
式は、new(d) foo(*d)
によって指されたオブジェクトを変更しd
ないままにしますか? より具体的には、クラスfoo
とその中に再帰的に含まれるすべてのオブジェクトに自明なコピーコンストラクターしかない場合、上記はnew(d) foo(*d)
当てはまります*d
か? そうでない場合はnew
、コピー コンストラクターを呼び出す前に、まずメモリをゼロにします。C++ 言語にそのような節はありますか?
編集: 誰かがこれをやりたいと思うのには、重要な理由があります。たとえば、CPU メモリから GPU メモリに、アドレス空間全体でオブジェクトをコピーすることを検討してください。そのための 1 つの解決策は、オブジェクトをバイト単位で処理することです。これは多くの場合に機能します。クラスに仮想メソッドがある場合、バイトごとのコピーによって vtable ポインターがコピーされ、これが一部の CPU メモリを指します。オブジェクトで上記の式を使用してnew(d) foo(*d)
、コンパイラに vtable ポインタを強制的にリセットさせることができます。
c++ - 「placement new」で割り当てられた「単純な POD クラス」のデストラクタを明示的に呼び出す必要がありますか?
ここで「単純」とは、非仮想の空のデストラクタまたは POD 型を持つクラスを意味します。
典型的な例:
で明示的なデストラクタを呼び出さないとどうなりp
ますか? 未定義の動作やメモリリークではないと思います。
再利用しても問題ありませbuffer
んか?
c++ - 同等の配置の新しい動作
new
C++での配置構文について質問があります。次の2つのコードスニペットは機能的に同等であり、交換可能に使用できますか(最初のコードスニペットが適切な場合、2番目のコードスニペットを使用する必要があることを意味するものではありません)。
#1
#2
このような配置構文を使用しているときに、特に注意する必要があることはありますか?
c++ - オブジェクトとして使用されるカプセル化された char 配列は厳密なエイリアシング ルールに違反しますか
次のクラスは厳密なエイリアシング ルールを破ります。
私の標準の読みは、それが正しくないということですが、よくわかりません (私の使用法は、オブジェクトの配列T
+ それらのオブジェクトのいくつかのメタデータを持ちますが、メモリを手動で割り当てずにオブジェクトの構築/分解を制御することです)。標準での配置の例として使用されnew
ます。
c++ - データ メンバーの有効期間を 1 つのメソッドに制限する
少し変わった問題に遭遇しました。次のコードを検討してください。
parse メソッドは、init
メソッドを使用してレクサーを初期化します。それ以前は、レクサーは使用できない「デフォルト」状態にあります。通常、構築中にメンバーを初期化する必要があるため、単純に次のようにします。
まず、これはクライアントが parse メソッドを複数回呼び出すことができることを意味しますが、これはあまり意味がありません。
2 つ目は、さらに重要なことですが、生涯にわたって重大な問題を簡単に引き起こす可能性があります。
上記のコードでは、行末で存在しなくなる一時的な文字列オブジェクトでレクサーが初期化されるためparse
、次の行でメソッドを呼び出すと、未定義の動作が呼び出されます。
これらの両方の理由から、私は本当に同じメソッドで初期化と解析を行いたいと考えています。残念ながら、結果を返す必要があり、コンストラクターは結果を返すことができないため、コンストラクターでそれを行うことはできません。
parse
技術的には、コンストラクタとデストラクタも適宜変更すれば、メソッド内でレクサーを構築し、後で破棄することが可能です。
しかし、これは私が非常に長い間書いた中で最も醜いコードです。また、例外セーフではありません。ヘルパー メソッドがスローするとどうなりますか? 実際、解析エラーが発生した場合は、まさにこれが発生します。
では、この問題をどのように解決すればよいでしょうか。内部でローカル レクサーを使用しparse
、lexer*
メンバーがそれを指すようにしますか? boost::optional<lexer>
メンバーを使用しますか?それとも、私はそのinit
方法で生きるべきですか?それとも、結局コンストラクターで解析を行い、目的の結果を含む「期待」をスローする必要がありますか?
c++ - const メンバを持つクラスの代入
次のコードを検討してください。
「const int id」はデフォルトの代入演算子を使用できないというコンパイラ エラーが発生します。
Q1. push_back() に代入演算子が必要なのはなぜですか?
A1. 現在のC++標準がそう言っているからです。
Q2. 私は何をすべきか?
- const指定子を手放したくない
- データをコピーしたい
A2. スマートポインターを使用します。
Q3. 私はかなり狂っているように見える「解決策」を思いつきました:
私はこれを避けるべきですか、なぜですか (もしそうなら)? オブジェクトがスタック上にある場合、placement new を使用しても安全ですか?
c++ - Reinterpret_cast vs プレースメント new
この投稿を読むと、事前に割り当てられたメモリ位置でクラス コンストラクターを呼び出すために C++ の配置ニュースが使用されていることが明らかです。
メモリが既に初期化されている場合、新しい配置または reinterpret_cast のどちらがより適切ですか?
たとえば、フレーム化されたメッセージを表す生のバイト ストリームを TCP ソケットから読み取ったとします。このストリームを framesync に入れ、クラスを表す既知のサイズのバッファーを取得します。これを Message と呼びます。私は、次の 2 つの方法を知っています。
クラスに初期化しないように指示するフラグを受け取るコンストラクターを作成します。「初期化しない」フラグを渡してバッファに新しい配置を行います。
/li>reinterpret_cast を使用する
/li>
どちらも同じ結果になると思います。どちらがより正確で、よりオブジェクト指向で、より安全で、読みやすく、またはより良いスタイルであるため、どちらが好まれますか?
c++ - 以前に初期化されたメモリは、配置の新しい呼び出し後に保持されることが保証されていますか?
私は次のものを持っているとしましょう:
aSecond
値が初期化されていなくても、2 番目のアサートは保持されることが保証されていますか? 論理的には、メモリは上書きされないため、そうすべきですが、標準で指定されていますか?