エラー、バグ、質問 - ページ 2794

 
Mihail Matkovskij:

私のインジケータは、何らかの理由でグラフィカルオブジェクトを失うようになり、それらを削除しないようになりました。クラスのデストラクタで自動削除するようにしています。と呼んでいます。

その結果、誤検出をしてしまうのです。GetLastError()を呼び出すと、エラー4101("Errorychart identifier")が表示されます。仮に削除されたグラフィカルオブジェクトのchartIDとChartID()関数の結果を比較すると、全く同じです。チャートからオブジェクトが削除されない理由は何でしょうか、またそれを回避するにはどうしたらよいでしょうか。

別の方法を試してみることにしました。チャート作成時に全オブジェクトをリストに追加し、インジケータ削除時に全オブジェクトを削除するループを使用しています。ObjectDelete 関数を呼び出した後、関数GetLastError() でエラー 4001 が発生し、いくつかのチャート・オブジェクトがチャート上に残るようになりました。

 
Mihail Matkovskij:

私のインジケータは、何らかの理由でグラフィカルオブジェクトを失うようになり、それらを削除しません。クラスのデストラクタで自動削除するようにしています。と呼んでいます。

その結果、誤検出をしてしまうのです。GetLastError()を呼び出すと、エラー4101("Errorychart identifier")が表示されます。仮に削除されたグラフィカルオブジェクトのchartIDとChartID()関数の結果を比較すると、全く同じです。チャートからオブジェクトが削除されない理由は何でしょうか、またそれを回避するにはどうしたらよいでしょうか。

このバグが発生するソースコードを作成しました。
//+------------------------------------------------------------------+
//|                                           DeleteChartObjects.mq5 |
//|                                      Copyright 2020, © Cyberdev. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, © Cyberdev."
#property version   "1.00"
#property indicator_chart_window

#property indicator_plots 0

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

#include <ChartObjects\ChartObjectsLines.mqh>
#include <Arrays\ArrayObj.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- input parameters
input int      nBars = 100000;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int customN_Bars = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CArrayObj listOfTrendLines;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
//--- indicator buffers mapping
  int totalBars = iBars(NULL, PERIOD_CURRENT);
  customN_Bars = (nBars < totalBars) ? nBars : totalBars;
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]
) {
  CChartObjectTrend * trend;
  int delta = rates_total - customN_Bars;
  int shift;
  int i;
  for(i = 0; i < customN_Bars; i++) {
    shift = delta + customN_Bars - i - 1;
    trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
  }
  return(rates_total);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}
//+------------------------------------------------------------------+

バグを実証するためのアクション

1. チャート上にインジケータを配置します。

2.チャートからインジケータを取り外します。

3 Ctrl+Bを押した後、ウィンドウ内の「List all」ボタンを押すと、削除されていないオブジェクトが表示されます。

対象物

10万人中294人もいるんですよ。

入力パラメータnBarsの値を小さくすると、不具合は発生しません。

ファイル:
 

こんにちは。

Windows7から10へのアップグレードでずっと足踏みしていましたが、今週再インストールしました。

今、問題があって、私の指標と他のEAのExpert Advisorデモバージョンをダウンロードすることができません。

ダウンロードボタンを押しても何も起こらないし、ターミナルを 開いた状態でも閉じた 状態でも試しました

MT4ターミナル用にダウンロードしようとしているのですが、MT5にはまだ手を出していません。

一体どうなっているんだ?

 
Mihail Matkovskij:
このバグが発生するソースコードを作成しました。

ポインターを削除するとどうなりますか?

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}

グラフに対して、グラフィカルオブジェクトを削除するコマンドはありますか?ObjectDelete の注記を参照してください。

Документация по MQL5: Графические объекты / ObjectDelete
Документация по MQL5: Графические объекты / ObjectDelete
  • www.mql5.com
При вызове ObjectDelete() всегда используется асинхронный вызов, поэтому функция возвращает только результат постановки команды в очередь графика. В этом случае true означает только то, что команда успешно поставлена в очередь, сам результат её выполнения неизвестен. Для проверки результата выполнения можно использовать функцию ObjectFind() или...
 
Mihail Matkovskij:

10万人 中294人もいるんですよ。

入力パラメータnBarsの値を小さくすると、この不具合は発生しません。

OnDeinitの実行時間よりもループが長く続くということは起こりえますか?

この例では、すべてのオブジェクトに "trend "という接頭辞がついていますが、それを使ってループから除外してはどうでしょう?

int  ObjectsDeleteAll(
   long           chart_id,   // идентификатор графика
   const string     prefix,   // префикс имени объекта
   int       sub_window=-1,   // индекс окна
   int      object_type=-1    // тип объекта для удаления
   );
 
Rashid Umarov:

ポインターを削除するとどうなりますか?

グラフに対して、グラフィカルオブジェクトを削除するコマンドはありますか?ObjectDeleteに関する 注記を参照してください。

確かにこのノートについては、以前から考えていました。でも、なぜか端末のバグだと判断したんです。それについては、申し訳なく思っています。だから、私のせいに違いない。

しかし、この場合、どうしたらいいのかわからない。ObjectDelete を呼び出した後、ObjectFind を呼び出し、 失敗するまで待って、実際にオブジェクトが削除されたかどうかを調べるのでしょうか?同ノートで判断すると、時間がかかりすぎる。2回目の削除がうまくいくかどうかはわかりません(私のインジケータでは、ObjectDeleteを2回続けて呼んでみましたが、うまくいきませんでした)。また、インジケーターのSleep機能は、各オブジェクトを削除するためにチャートに時間を与えるために機能しません。もしかしたら、これを回避するための事例がどこかにあるのかもしれません。

 
Alexey Viktorov:

OnDeinitの実行時間よりループが長くなることはないのでしょうか?

結局のところ、あなたの例のすべてのオブジェクトは "トレンド "の接頭辞を持っている、なぜそれを使用し、ループから拒否しないのですか?

これはあくまで例としてです。私が扱っているインジケータは名前が複雑です。そして、デモンストレーションのために例を挙げました。

 
Mihail Matkovskij:

確かにこのノートは以前から思っていました。でも、その後、なぜか端末のバグだと思ったんです。その点については、申し訳なく思っています。結局は私のせいなんですけどね。

しかし、この場合、どうしたらいいのかわからない。ObjectDelete を呼び出した後、ObjectFind を呼び出し、 失敗するまで待って、実際にオブジェクトが削除されたかどうかを調べるのでしょうか?同じノートで判断すると、時間がかかりすぎる。2回目の削除がうまくいくかどうかはわかりません(私のインジケータでは、ObjectDeleteを2回続けて呼んでみましたが、うまくいきませんでした)。また、インジケーターのSleep機能は、各オブジェクトを削除するためにチャートに時間を与えるために機能しません。もしかしたら、どこかにこれを回避する事例があるかもしれませんね。

全ポインターを追加しているのでは?端末サブシステムは、CArrayObjの リストにあるポインタを持つこのようなオブジェクトを自ら削除します。

trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
ここで、メモリリークの可能性があります。そして、無効なオブジェクトを呼び出す可能性があること。
 
Artyom Trishkin:
すべてのポインターを追加していますね。端末サブシステムは、CArrayObjのリストにあるオブジェクトへのポインタを自ら削除します。

端末をシャットダウンした後も、インジケーターの後にオブジェクトがチャート上に残ります。そして、再びターミナルを起動 すると、これらのオブジェクトが表示され、全体のビューを台無しにしています。

 
Mihail Matkovskij:

端末をシャットダウンした後も、インジケーターの後にオブジェクトがチャート上に残ります。そして、再びターミナルを起動 すると、これらのオブジェクトが表示され、全体のビューを台無しにしています。

私はPCの前にいないので、あなたの例を確認することができません。上記の投稿に、エラーで表示される内容を追記しました。