2017-07-27 5 views
3

C#とC++のアンマネージコードで作業していますが、メモリを扱うときにわからない2つのことがあります。C#とC++で作業しているときのメモリ割り当て/割り当て解除

  1. を変数は動的に(新しいを使用して)C#の下に割り当てられ、その後、C++アンマネージコードに渡された場合:誰かが私を理解するのに役立つことができます。その可変メモリは、C++アンマネージコードの下でユーザによって手動で割り当て解除される必要がありますか?

  2. 変数がC++で動的に割り当てられていて(新しいものを使用して)管理されていて、C#に渡された場合、ガベージコレクタがそのメモリを割り当て解除すると言うのは安全でしょうか?経験則として

答えて

2

これは本当に簡単です!

  1. を依存していることについては申し訳ありませんええ、

を依存します。典型的な条件の下で

  1. 、C#がメモリを追跡し、それはもはやC#の側にを使用しています後であればいつでもそれを取り除くでしょう。これはC++側で参照を追跡する方法がないため、interopのよくある間違いの1つは、メモリがに割り当て解除されてから、管理されていない側がで終了する(FUNの負荷がかかる)ということです。これは、メモリが直接参照され、コピーされたときではなく、メモリが直接参照される場合にのみ適用されます(典型的な場合は、アンマネージドコールの期間固定されます)。アンマネージコードに渡されるオブジェクト/ポインタの存続期間が、呼び出されたメソッドの実行よりも長いと想定されている場合は、自動マーシャリングを使用しないでください。
  2. 一般的な条件下では、C#はC++コードのメモリ割り当てを追跡する方法がないため、自動メモリ管理に頼ることはできません。例外(例:いくつかのCOMシナリオ)がありますが、ほとんどの場合、手動でメモリを管理する必要があります。これは通常、何らかの種類のグローバルアロケータ(例えば、CoMemoryInitialize)を使用していない限り、ポインタをC++コードに戻して割り当てを解除することを意味します。管理されていない世界では、メモリを処分するために安全に呼び出すことのできるメモリマネージャは存在しません。あなたは本当に必要な情報を持っていません。

これはもちろんポインタにのみ当てはまります。整数を渡すことはまったく問題ありません。自動マーシャリングを使用することは、通常、マーシャリング担当者が微妙なことの大部分を処理することを意味します(ただし、最も単純な場合でも注意してください)。アンマネージコードアンマネージド - メモリがどのように割り当てられているか、どのようにいつ、誰がメモリをクリーンアップするのかを完全に理解する必要があります。

+0

>相互運用の一般的な間違いは、アンマネージド側が完了する前にメモリの割り当てを解除することです。 https://msdn.microsoft.com/en-us/library/system.gc.keepalive.aspxを参照してください。 – Wollmich

1

、いずれcomponent/objectメモリがメモリの割り当てを解除する必要があり割り当てます。 newの場合はdeleteの場合はnewとなりました。

これは理想です。 C++などの理由でプログラムが終了し、割り当てられたメモリのライフサイクルが終了しても存在しない場合は、C#をクリーンアップし、その逆を行う必要があります。

2
  1. いいえ、オブジェクトが管理されたヒープに割り当てられているため、GCはいつものように割り当て解除を処理します。問題は、アンマネージコードからオブジェクトを使用する期間をGCが知ることができないため、アンマネージコードからオブジェクトを解放したり、オブジェクトのアドレスを変更しないように指示しなければならないことです。これは、オブジェクトをPINNINGすることによって行うことができます。 thisの質問への回答を参照してください。

  2. いいえ、オブジェクトはC++で割り当てられているため、管理されていないヒープGCはそれに手を加えません。削除を使用して自分自身の割り当てを解除する必要があります。

編集: あなたがアンマネージコードまたはその逆にマネージコードとDEALLOCATEにオブジェクトを割り当てる必要がある場合は、それはあなたがからMarshal.AllocHGlobalMarshal.FreeHGlobal呼び出しを経由して使用することができ、この目的のために、OSのヒープがある知って良いことですC#では、C++で同様の呼び出しが行われます。

関連する問題