"ダミー "からの質問 - ページ 107

 
mql5:
MQL5ではデストラクタは常に仮想です。デストラクタにPrint(__FUNCSIG__);を入れてみると、すべて正しく削除されます。


VC++でやりましたが、メモリ解放の 仕組みは同じではないでしょうか?
Документация по MQL5: Основы языка / Операторы / Оператор уничтожения объекта delete
Документация по MQL5: Основы языка / Операторы / Оператор уничтожения объекта delete
  • www.mql5.com
Основы языка / Операторы / Оператор уничтожения объекта delete - Документация по MQL5
 
220Volt:
VC++でやりましたが、メモリ解放の 仕組みは同じだと思うのですが?
いいえ、C++では、deleteでオブジェクトを正しく削除するためには、仮想デストラクタを指定する必要があります。

しかし、この例では、ベース・クラスに対してのみ virtual destructor を指定することができるので、正しく動作します。
 

少し違う言い方で考えてみます。

与えられた。

  • クラス#1 - メモリ内に100バイトを占有します。
  • クラス#2 - クラス#1の子孫で、メモリ内で200バイトを占有しています。
  • クラス#1へのポインタ。

行動する。

  • クラス#2のインスタンスが存在するメモリセクションのアドレスをポインタに書き込む(newを呼び出す)
  • ポインタに格納されたアドレスにdelete関数を渡して、ハンダ領域を解放する。

追伸:図はメモリモデルです )

 
クラス番号1のポインタが、実はクラス番号2がメモリ上にあるため、疑問がある。デストラクタの場合は問題ないので、ここにも問題があるのではと思いました。このような状況では、メモリ内にラベル(ヌルターミネータ付きのcharなど)がある場合のみ、正しいメモリ解放が 行われると思いますので、メモリ割り当てについて質問させていただきました。
 
220Volt:
クラス番号1へのポインタが、実際にはメモリ上のクラス番号2であるため、疑義がある。デストラクタの場合は問題ないので、もしかしたらここでも問題があるのかなと思いました。このような状況では、メモリ 内にラベル(ゼロ終端を持つcharなど)がある場合のみ、正しいメモリ解放が 可能だと思いますので、メモリ割り当てについて質問させていただきました。

あなたの疑問は、コンストラクタを指定していないからです(この場合、何が起こっているかを理解することが重要です)。この例を実行してみれば、すべてが理解できるはずです。

class CFoo
  {
public:
                     CFoo() { Print(__FUNCSIG__); }
                    ~CFoo() { Print(__FUNCSIG__); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CBar : public CFoo
  {
public:
                     CBar() { Print(__FUNCSIG__); }
                    ~CBar() { Print(__FUNCSIG__); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CFoo *f=new CBar();

   delete f;
  }
//+------------------------------------------------------------------+

HZでは、構築そのものと削除をずらし、その情報をすべて記憶し(仮想ポインタ自体が、ベースと子孫の合成クラスとして構築されたことを記憶する)、削除の際には、後のものから先のものへと、逆順にデストラクタを呼び出すようにしています。

 
デストラクタの問題ではなく、クラス自体の問題であり、より正確には何バイトを占有するかが問題です。200バイトを確保し、サイズ100バイトのオブジェクトを表すポインタが指すメモリを解放するように指示することがわかった。
 
220Volt:
デストラクタの問題ではなく、クラス自体の問題であり、より正確には、クラスが占めるバイト数の問題です。200バイトを確保し、100バイトの大きさのオブジェクトを表すポインタが指すメモリを解放するように指示することがわかったのです。
ご質問は、メモリープールの仕組みに関係するものですね。
はい、メモリプールは、deleteコールによってメモリ片が解放される時間を知っています。
この情報がどこに格納されるかは、プールの実装に依存する。

例えば、C++でnewで確保されないオブジェクトへのポインタを与えた場合、アプリケーションがクラッシュすることがおわかりいただけると思います。
 
220Volt:
デストラクタの問題ではなく、クラス自体の問題であり、より正確には、クラスが占めるバイト数の問題です。200バイトを確保し、100バイトの大きさのオブジェクトを表すポインタが指すメモリを解放するように指示することがわかったのです。
私のサンプルを使っていないのですね。そうでなければ、このような質問をしないでしょう。
 
考えていたら、例えばintの配列にメモリを割り当てて、1つのintが小さいにもかかわらず、それを全部削除できることを思い出した、おそらくクラスも同じだろう。回答ありがとうございました。
 
mql5:
ご質問は、メモリープールの仕組みに関係するものだと理解しています。
はい、メモリプールは、deleteコールによってピースが解放されるまでの時間を知っています。
この情報がどこに格納されるかは、プールの実装に依存する。

例えば、C++でnewで割り当てられなかったオブジェクトへのポインタを与えた場合、アプリケーションがクラッシュすることがお分かりいただけると思います。
そんな感じです、ありがとうございました。