오류, 버그, 질문 - 페이지 2794

 
Mihail Matkovskij :

어떤 이유로 내 표시기가 그래픽 개체를 잃기 시작하고 삭제하지 않습니다. 클래스 소멸자에서 자동 삭제를 사용합니다. 나는 전화한다:

결과적으로 나는 거짓을 얻는다. GetLastError()를 호출하고 오류 4101("잘못된 차트 ID ")을 얻습니다. 예를 들어... 제거된 그래픽 개체의 chartID를 ChartID() 함수의 결과와 비교했는데 정확히 동일합니다. 차트에서 개체를 삭제하지 않는 이유는 무엇이며 어떻게 우회할 수 있습니까?

다른 것을 시도하기로 결정했습니다. 생성할 때 모든 차트 개체를 목록에 추가하고 지표를 삭제할 때 루프를 사용하여 모든 개체를 삭제합니다. 이제 GetLastError() 함수는 ObjectDelete 함수를 호출한 후 오류 4001을 제공 하고 일부 차트 개체는 여전히 차트에 남아 있습니다.

 
Mihail Matkovskij :

어떤 이유로 내 표시기가 그래픽 개체를 잃기 시작하고 삭제하지 않습니다. 클래스 소멸자에서 자동 삭제를 사용합니다. 나는 전화한다:

결과적으로 나는 거짓을 얻는다. GetLastError()를 호출하고 오류 4101("잘못된 차트 ID ")을 얻습니다. 예를 들어... 제거된 그래픽 개체의 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를 누른 다음 창에서 "모두 나열" 버튼을 누르고 삭제되지 않은 개체를 봅니다.

사물

100,000개 중 294개 남았습니다.

입력 매개변수 nBars의 값을 줄이면 버그가 나타나지 않습니다.

파일:
 

안녕하세요.

오랫동안 Windows 7에서 10으로 전환하면서 고무를 뽑았지만 일주일 만에 다시 설치했습니다.

이제 문제가 있습니다. 나와 다른 사람의 지표에 대한 Expert Advisors의 데모 버전을 다운로드할 수 없습니다.

다운로드 버튼을 눌러도 아무 일도 일어나지 않고, 터미널을 열었다 닫았다 하고 해봤습니다 !?

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 :

100,000 개 중 294개 정도 남았습니다.

입력 매개변수 nBars의 값을 줄이면 버그가 나타나지 않습니다.

주기가 OnDeinit 실행에 할당된 시간보다 오래 지속되는 경우는 없을까요?

결국, 귀하의 예에서 모든 객체에는 "추세" 접두사가 있습니다. 이것을 활용하고 주기를 포기하지 않으시겠습니까?

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

포인터가 삭제되면 어떻게 됩니까?

그래픽 개체를 삭제하는 그래픽 명령이 있습니까? ObjectDelete 에 대한 참고 사항을 참조하십시오.

나는 확실히 이전에 이 메모에 대해 생각한 적이 있습니다. 그러나 어떤 이유로 나는 그것이 터미널 버그라고 결정했습니다. 이에 대해 사과드립니다. 내 잘못이 밝혀졌습니다.

하지만 이 경우 어떻게 해야 할지 모르겠습니다. ObjectDelete를 호출한 다음 ObjectFind 를 호출하고 개체가 실제로 삭제되었는지 확인하기 위해 완료될 때까지 기다립니다. 같은 메모에 따르면 이것은 시간이 너무 많이 걸립니다. 그리고 반복 삭제가 작동하는지 모르겠습니다(내 표시기에서 ObjectDelete를 연속으로 두 번 호출하려고 시도했지만 아무 소용 없었습니다). 그리고 지표의 Sleep 기능은 차트가 각 개체를 제거하는 데 약간의 시간을 주기 위해 작동하지 않습니다. 이 문제를 해결하는 방법에 대한 예가 어딘가에 있습니까?

 
Alexey Viktorov :

주기가 OnDeinit 실행에 할당된 시간보다 오래 지속되는 경우는 없을까요?

결국, 귀하의 예에서 모든 객체에는 "추세" 접두사가 있습니다. 이것을 활용하고 주기를 포기하지 않으시겠습니까?

이것은 단지 예에 있습니다. 내가 작업하고 있는 지표에서 이름은 다소 복잡합니다. 그리고 시연을 위해 예제를 만들었습니다.

 
Mihail Matkovskij :

나는 확실히 이전에 이 메모에 대해 생각한 적이 있습니다. 그러나 어떤 이유로 나는 그것이 터미널 버그라고 결정했습니다. 이에 대해 사과드립니다. 내 잘못이 밝혀졌습니다.

하지만 이 경우 어떻게 해야 할지 모르겠습니다. ObjectDelete를 호출한 다음 ObjectFind 를 호출하고 개체가 실제로 삭제되었는지 확인하기 위해 완료될 때까지 기다립니다. 같은 메모에 따르면 이것은 시간이 너무 많이 걸립니다. 그리고 반복 삭제가 작동하는지 모르겠습니다(내 표시기에서 ObjectDelete를 연속으로 두 번 호출하려고 시도했지만 아무 소용 없었습니다). 그리고 지표의 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 :

터미널이 완료된 후 차트의 개체는 표시기 뒤에 남습니다. 그리고 터미널을 다시 시작하면 이러한 개체가 표시되고 전체 보기가 손상됩니다.

나는 당신의 예를 테스트하기 위해 내 컴퓨터에 있지 않습니다. 나는 내가 오류로 보는 것을 위의 나의 포스트에 보충했다.