Erros, bugs, perguntas - página 2794

 
Mihail Matkovskij:

O meu indicador começou a perder objectos gráficos por alguma razão e não os apaga. Utilizo a eliminação automática no destruidor de classes. Eu chamo-lhe:

Como resultado, recebo um falso positivo. Chamo GetLastError() e recebo o erro 4101 ("Errory chart identifier"). Suponha-se. Comparo o chartID do objecto gráfico eliminado com o resultado da função ChartID() e eles são exactamente os mesmos. Qual pode ser a razão para não remover um objecto do mapa e como posso contorná-lo?

Decidi tentar de outra forma. Ao criar um gráfico, adiciono todos os objectos à lista e utilizo o laço para apagar todos os objectos ao apagar o indicador. Agora a funçãoGetLastError() dá erro 4001 após a chamada de função ObjectDelete e alguns objectos do gráfico permanecem no gráfico.

 
Mihail Matkovskij:

O meu indicador começou a perder objectos gráficos por alguma razão e não os apaga. Utilizo a eliminação automática no destruidor de classes. Eu chamo-lhe:

Como resultado, recebo um falso positivo. Chamo GetLastError() e recebo o erro 4101 ("Errory chart identifier"). Suponha-se. Comparo o chartID do objecto gráfico eliminado com o resultado da função ChartID() e eles são exactamente os mesmos. Qual pode ser a razão para não remover um objecto do mapa e como posso contorná-lo?

Fiz um código fonte onde este erro ocorre:
//+------------------------------------------------------------------+
//|                                           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;
  }
}
//+------------------------------------------------------------------+

Acções para demonstrar o bug.

1. colocar o indicador no gráfico.

2. Retirar o indicador do gráfico.

3 Prima Ctrl+B, depois prima o botão "Listar tudo" na janela e veja os objectos que não foram removidos.

Objectos

Tenho até 294 de um total de 100000.

Se se reduzir o valor do parâmetro de entrada nBars, o bug não aparece.

Arquivos anexados:
 

Boa tarde.

Há muito tempo que tenho vindo a empatar com a actualização do Windows 7 para 10, mas reinstalei esta semana.

Agora tenho um problema, não posso descarregar versões de demonstração do Expert Advisor dos meus indicadores e outros EAs,

Carrego no botão de descarga e nada acontece, experimentei-o com o terminal aberto e fechado!

Estou a tentar descarregá-lo para o terminal MT4, ainda não estive no MT5.

Que diabos se passa?

 
Mihail Matkovskij:
Fez um código fonte onde este erro ocorre:

O que acontece quando um ponteiro é apagado?

//+------------------------------------------------------------------+
//| 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;
  }
}

Existe algum comando no gráfico para apagar o objecto gráfico? Ver nota ao ObjectDelete

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

Tenho até 294 de um total de 100000.

Se diminuirmos o valor do parâmetro de entrada nBars, o bug não ocorre.

Pode acontecer que o laço dure mais tempo do que o necessário para executar o OnDeinit?

No seu exemplo, todos os objectos têm prefixo "tendência", porque não o utiliza e recusa do laço?

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

O que acontece quando um ponteiro é apagado?

Existe algum comando no gráfico para apagar o objecto gráfico? Ver a nota sobre ObjectDelete

Já pensei certamente nesta nota antes. Mas depois decidi, por alguma razão, que se tratava de um bug do terminal. Pelo qual peço desculpa. Portanto, a culpa deve ser minha.

Mas eu não sei o que fazer neste caso. Chamo ObjectDelete e depois ObjectFind e espero até que não consiga descobrir se o objecto foi realmente removido? A julgar pela mesma nota, é demasiado demorado. Não sei se uma segunda eliminação irá funcionar (no meu indicador tentei chamar ObjectDelete duas vezes seguidas, mas não funcionou). E a função Dormir nos indicadores não funciona para dar ao gráfico algum tempo para eliminar cada objecto. Talvez haja exemplos algures sobre como contornar isto?

 
Alexey Viktorov:

Não pode acontecer que o laço dure mais do que o tempo permitido para executar o OnDeinit?

Afinal, todos os objectos do seu exemplo têm prefixo "tendência", porque não usá-lo e recusar o laço?

Isto está apenas no exemplo. O indicador com o qual estou a trabalhar tem nomes complexos. E dei um exemplo apenas para fins de demonstração.

 
Mihail Matkovskij:

Pensei certamente nesta nota antes. Mas depois, por alguma razão, pensei que se tratava de um bug terminal. Pelo qual peço desculpa. Acontece que a culpa é minha.

Mas eu não sei o que fazer neste caso. Chamo ObjectDelete e depois ObjectFind e espero até que não consiga descobrir se o objecto foi realmente removido? A julgar pela mesma nota, é demasiado demorado. Não sei se uma segunda eliminação irá funcionar (no meu indicador tentei chamar ObjectDelete duas vezes seguidas, mas não funcionou). E a função Dormir nos indicadores não funciona para dar ao gráfico algum tempo para eliminar cada objecto. Talvez haja exemplos, algures, de como contornar isto?

Penso que está a acrescentar todas as indicações à lista. O próprio subsistema terminal remove tais objectos, ponteiros para os quais estão na lista CArrayObj

trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
Aqui tem uma potencial fuga de memória. E uma potencial invocação de um objecto inválido.
 
Artyom Trishkin:
Penso que se acrescentam todas as indicações à lista. O próprio subsistema terminal apaga tais objectos, apontadores para os quais estão na lista CArrayObj

Após o encerramento do terminal, os objectos permanecem na tabela após o indicador. E quando inicio o terminal novamente, estes objectos são visíveis e estragam toda a vista.

 
Mihail Matkovskij:

Após o encerramento do terminal, os objectos permanecem na tabela após o indicador. E quando inicio o terminal novamente, estes objectos são visíveis e estragam toda a vista.

Não estou no meu PC para verificar o vosso exemplo. Acrescentei ao meu post acima o que vejo em erros.
Razão: