問題タブ [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++ - これを削除し、仮想的に派生したクラスの新しい配置
これは、短く、自己完結型で、正しい(コンパイル可能)、私のコードの例です(これは基本的any_iterator
に私自身の成長のために再発明されています)。
質問は次のようになります。共有ベース上に追加のメンバーがない場合に、同じベースから仮想的に派生した別のタイプで破棄this
および再構築するのは未定義の動作ですか?this
具体的には、コンパイラーは静的型を追跡する呼び出しを許可されていますか、それとも技術的に不適合ですか?
derivedA
[編集]スタック上に作成された場合、コンパイラが誤ったデストラクタを呼び出す可能性があることを指摘する人もいます。(1)コンパイラがそうすることを可能にする標準には何も見つかりません。(2)それは私の質問で意図したこととは別に、スタックに配置 derived
できないことを示すようにコードを変更しました。base
ただし、スタックに残すことはできます。
c++ - この配置new[]の使用の何が問題になっていますか?行う
以下のプログラムを検討してください。複雑なケースから簡略化されています。Objクラスの仮想デストラクタを削除しない限り、以前に割り当てられたメモリの削除に失敗します。仮想デストラクタが存在する場合にのみ、プログラムの出力からの2つのアドレスが異なる理由がわかりません。
これは、仮想デストラクタが存在する場合の私の実装でのプログラムの出力です。
割り当てられたメモリアドレスは0x8895008から始まります割り当て解除されるメモリは0x889500cから始まります
RUN FAILED(終了値1)
それが何をすることになっているのか尋ねないでください。私が言ったように、それはアリーナがさまざまなタイプのメモリのインターフェースであるというより複雑なケースから来ています。この例では、メモリはヒープから割り当てられ、割り当てが解除されています。
c++ - 配置 new が呼び出されたときに、ポインタを「void*」にキャストすると効果がありますか?
カスタム コンテナーのコードを確認していて、その一部で次のような要素が作成されます。
そして、いくつかは次のようにします:
したがって、両方とも配置 new を使用してコピー コンストラクターを呼び出し、他の要素をコピーして要素を作成しますが、ある場合には新しい要素ストレージへのポインターがそのまま渡され、別の場合には にキャストされvoid*
ます。
このキャストvoid*
は何か効果がありますか?
c++ - C++ - 演算子 new をオーバーロードし、追加の引数を提供する
operator をオーバーロードできることはわかっていますnew
。size_t
そうすると、デフォルトでメソッドにパラメーターが送信されます。ただし、size_t
パラメーターと追加のユーザー指定パラメーターをオーバーロードされたnew
オペレーターメソッドに送信することは可能ですか?
例えば
このように新しい演算子をオーバーライドしたいので
ありがとう
編集:これが私が達成したいことです:
アプリの開始時に割り当てられた仮想メモリのチャンク (メモリ プール) があります。基本クラスを継承するすべてのオブジェクトは、オーバーロードされた new 演算子を継承します。オーバーロードされた new で引数を渡したい場合があるのは、メモリ プールを使用するか、malloc で割り当てるかをメモリ マネージャーに伝えるためです。
c++ - アレイの配置-新規では、バッファーに不特定のオーバーヘッドが必要ですか?
[expr.new]
C ++112月ドラフトの5.3.4に例を示します。
new(2,f) T[5]
の呼び出しになりoperator new[](sizeof(T)*5+y,2,f)
ます。ここで、xとyは、配列割り当てのオーバーヘッドを表す非負の未指定の値です。new-expressionの結果は、によって返される値からこの量だけオフセットされ
operator new[]
ます。このオーバーヘッドは、ライブラリ関数やその他の配置割り当て関数を参照するものを含む、すべての配列の新しい式に適用される可能性があります。operator new[](std::size_t, void*)
オーバーヘッドの量は、newの呼び出しごとに異なる場合があります。—例を終了]
次に、次のサンプルコードを使用します。
上記の引用によると、2行目は(個々のオブジェクトを作成する前に)new (buffer) std::string[10]
内部的に呼び出します。問題は、の場合、事前に割り当てられたバッファが小さすぎることです。operator new[](sizeof(std::string) * 10 + y, buffer)
std::string
y > 0
では、配列配置を使用するときに事前に割り当てるメモリの量をどのように知ることができますか?
それとも、この場合、標準はどこかでそれを保証していy == 0
ますか?繰り返しますが、引用は次のように述べています。
このオーバーヘッドは、ライブラリ関数やその他の配置割り当て関数を参照するものを含む、すべての配列の新しい式に適用される可能性があります。
operator new[](std::size_t, void*)
c++ - 同じ変数を使用して新しいオブジェクトを破棄して構築します
最初からやり直すのが良い場合もあります。C ++では、次の簡単な操作を使用できます。
スコープの最後で、デストラクタが再度実行され、すべてが正常に表示されます。(またT
、少し特別で、割り当てられるのは好きではありません。交換は言うまでもありません。)しかし、すべてを破壊して再試行することは必ずしもリスクがないわけではないということを教えてくれます。このアプローチで問題が発生する可能性はありますか?
c++ - 同じアドレスで 2 回構築されたオブジェクトに対して、2 番目のデストラクタを呼び出す必要があることをコンパイラはどのように認識しますか?
次のコードでは、sub
クラス内のオブジェクトがC
2 回作成されます。最初の構成はデフォルトの ctor を呼び出し、 2 番目の構成は このオブジェクトを同じアドレスに再Sub()
構築するために使用します。placement new
したがって、デストラクタも 2 回呼び出されます。Sub
最初の呼び出しはdtorへの直接呼び出しを使用し~C()
、2 番目の呼び出しは の終了後に関数main()
によって呼び出されると思いatexit()
ます。
オブジェクトsub
が同じアドレスで再構築される場合、コンパイラは 2 番目のデストラクタを の後に呼び出す必要があることをどのように認識しmain()
ますか? 彼はこの情報をどこに保管していますか?
c++ - 新しい配置によって割り当てられたメモリを適切に解放する方法は?
プレースメント newを使用する場合は、デストラクタを手動で呼び出す必要があることを読んだことがあります。
次のコードを検討してください。
私の知る限り、オペレーターdelete
は通常、デストラクタを呼び出してからメモリの割り当てを解除しますよね? delete
では、代わりに使用しないのはなぜですか?
nullptr
最初のケースでは、次のようにデストラクタを呼び出した後にpMyClass を強制的に設定します。
しかし、デストラクタはメモリの割り当てを解除しませんでしたよね? それで、それはメモリリークでしょうか?
私は混乱しています、あなたはそれを説明できますか?
c++ - mallocと配置の新規vs.新規
私は過去数日間これを調査してきましたが、これまでのところ、独断的な議論や伝統への訴え(つまり「C ++の方法です!」 )以外に説得力のあるものは見つかりませんでした。
オブジェクトの配列を作成している場合、以下を使用する理由は何ですか(使いやすさ以外)。
以上
私が知る限り、後者は前者よりもはるかに効率的であり(メモリをいくつかの非ランダム値に初期化したり、デフォルトのコンストラクターを不必要に呼び出したりしないため)、唯一の違いは、クリーンアップするという事実です。 :
そしてあなたが片付ける他のもの:
私はやむを得ない理由で外出しています。それがC++(Cではない)であり、したがって使用されるべきではないという事実にアピールすることはmalloc
、free
私が知る限り、独断的であるほど説得力がありません。私が見逃しているものよりも優れているものはありますか?new []
malloc
つまり、私が知る限りnew []
、デフォルトのパラメーターなしのコンストラクターを持たないものの配列を作成するために、malloc
メソッドを使用することはできますが、まったく使用することはできません。
c++ - このコードがコピー コンストラクターを呼び出そうとしているのはなぜですか?
Visual Studio でコンパイル エラーをいじるのに途方もない時間を費やしました。コードを以下の小さなコンパイル可能な例に抽出し、IdeOne で試してみたところ、ここで確認できる同じエラーが発生しました。
B(const B&)
次のコードが代わりに呼び出そうとするのはなぜだろうと思っていますB(B&&)
:
コンストラクターを明示的に定義していないのでB(std::move(binst))
、コンパイラーを generated と呼ぶ必要がB(B&&)
ありますか?
私がに変更B
するとき
それはうまくコンパイルされます。どうしてこれなの?
例のように配置 new および move コンストラクターを使用するテンプレート クラスがあるため、これを基本クラスから修正できないと非常に不便です。私のテンプレート クラスで使用するための要件ではありません)、明示的に定義された移動コンストラクターを持つ必要があります。