为什么自定义 class 的动态数组会导致内存泄漏?

Why memory leaks with a dynamic array of a custom class?

我正在创建一个识别烛条形状的指标。

为此,我创建了一个单独的 class Candlestick,并将其包含在指标文件中。

问题是我有内存泄漏问题。

我是指针的新手,在阅读/观看了很多之后,我似乎仍然遗漏了一些东西。

这是指标 class。 Candlestick class 的内容无关紧要,所以我将其省略。

Candlestick *candles[]; 

void OnDeinit(const int reason)
{
    for(int i = 0; i < ArraySize(candles); i++ ){
      delete(candles[i]);
    }
}

int OnCalculate(args here)
{
    ArrayResize(candles, Bars);

    for(int i = MathMax(Bars-2-IndicatorCounted(), 1); i >= 0; i--)
    {            
        candles[i] = new Candlestick();

        // Do stuff with this candle (and other candles) here e.g.
        if(candles[i+1].type == BULLISH) Print("Last candle was Bullish");
    }
}

当我这样做时,出现内存泄漏错误。看来我需要删除指向该动态数组中蜡烛的指针。问题是,when and where? 因为我在 for(){...}[= 的下一次迭代中需要它们36=] 循环。所以我不能在那里删除它。

当我在 OnDeinit() 函数中删除它时,那里仍然有蜡烛,但我仍然收到泄漏错误。

怎么会?

首先,尼克,欢迎来到 MQL4

的世界

您可能已经意识到,MQL4 代码不是 C.

在许多重要差异中,这里的关键是代码执行平台(MetaTrader Terminal 4)在什么时候做什么。

OnCalculate() 是一个类似僵尸的进程,被调用多次,但无论如何,绝对不受你控制.

接下来,OnCalculate() 设计并不意味着新的 Bar


怎么办?

MQL4 在概念上起源于几天,当时计算资源在代码执行阶段的分时 CPU-MUX-ing 方面更小且更昂贵。

因此,MQL4-用户域语言保留了一些无法直接访问的隐藏宝石的优点。其中之一是非常有效的基于寄存器的更新处理和保持最小的动态资源分配,因为它们对实时执行的可预测性具有毁灭性的不利影响。

这将帮助您了解如何更智能地设计和处理您的概念对象,最好是模仿这个 "stone-age"-但是-非常-高效 行为(时间和内存方面),而不是在每次调用 OnCalulate() 时用无限量的非托管实例淹没你的内存池,这会洒出无穷无尽的 new Candlestick(); // *--> candles[]


最好的下一步:

如果有疑问,请阅读平台 localhost-help/documentation 中 ArrayResize() 的最佳实践,以开始意识到引入开销的事情(如果不是块)在一个域中,其中 nano$econd$ 在专业软件设计中很重要并受到伤害。