在mt5上遇到了个错误(除非你们不复用函数),他的函数不能根据入口点重新开辟内存空间?当同一个函数重复使用时,很容易出现错误。

 
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   int allBarCount;
   allBarCount=Bars(_Symbol,_Period);
   string sname;
   ENUM_TIMEFRAMES pname;
   sname=Symbol();
   pname=Period();
   double h[];

   CopyHigh(sname,pname,0,allBarCount,h);

   static int bb1[],bb2[];
   test(h,bb1,allBarCount);//这里得出bb1的结果
   test(h,bb2,allBarCount);//当引用bb2,而不是bb1时应该当作新的函数,重新开辟内存空间。
   myPrintArray(bb2);
   if(allBarCount>100)
      ExpertRemove();
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void test(const double &a[],int &bbb[],int barno)
  {
   ArrayResize(bbb,barno);
   static int start=0;
   for(int i=start; i<barno; i++)
     {
      if(a[i]>0.000001)
        {
         bbb[i]=1;
        }
      else
        {
         bbb[i]=0;
        }
     }
   start=barno-1;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void myPrintArray(const int &ar[])
  {
   int s=ArrayRange(ar,0);
   for(int i=0; i<s; i++)
     {
      Print("Array[",i,"/",s,"]:",ar[i]);
     }
  }
//+------------------------------------------------------------------+

上面是个EA,启动策略测试工具,随便选个时间段,点开始,然后程序会退出,再点一次,发现了什么?是不是数据乱了?


PS:这只是个例子,真正的问题出现在这个函数嵌套在其他函数体内使用时,相互也干扰.

比如

a(){
test(high);
}

b(){
c(low);
}

c(double &low[]){
test(low);
}

这样使用时,之间也会相互干扰.
 

有些API函数,最好确认其返回值。


void OnTick()
  {
   int allBarCount;
   allBarCount=Bars(_Symbol,_Period);
   
   if(allBarCount<=0)return;
   
   
   string sname;
   ENUM_TIMEFRAMES pname;
   sname=Symbol();
   pname=Period();
   double h[];

   int copied = CopyHigh(sname,pname,0,allBarCount,h);
   if(copied<=0)return;
   if(copied!=allBarCount)return;//这个根据你实际需求
   

   static int bb1[],bb2[];
   test(h,bb1,copied);//这里得出bb1的结果
   test(h,bb2,copied);//当引用bb2,而不是bb1时应该当作新的函数,重新开辟内存空间。
   myPrintArray(bb2);
   if(allBarCount>100)
      ExpertRemove();
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void test(const double &a[],int &bbb[],int barno)
  {
  
   if(barno>0) ArrayResize(bbb,barno);
   else return;
   
   static int start=0;
   for(int i=start; i<barno; i++)
     {
      if(a[i]>0.000001)
        {
         bbb[i]=1;
        }
      else
        {
         bbb[i]=0;
        }
     }
   start=barno-1;
  }
 
Ziheng Zhuang:

有些API函数,最好确认其返回值。

逻辑要严谨,能多啰嗦几句的绝对不能省略·····

 
solrv:

上面是个EA,启动策略测试工具,随便选个时间段,点开始,然后程序会退出,再点一次,发现了什么?是不是数据乱了?


PS:这只是个例子,真正的问题出现在这个函数嵌套在其他函数体内使用时,相互也干扰.

比如

我也没特别明白你的意思,但是你最后那几行,当然会有“干扰”啊;

反而有“干扰”才是正常的,因为从代码上看你就是想要那样的结果!

否则,应该去掉函数传进去的参数前面的&符号,函数变成

void test(double a,double b[])
{
  ……
}
//不能是下面这样有&符号
void test(double&a,double&b[])
{
  ……
}
 
Ziheng Zhuang:

有些API函数,最好确认其返回值。

if(allBarCount<=0)return;
我老天,会出这种事。。。这种情况你要不说我想都想不到。。。
 
Tiecheng Fu:

逻辑要严谨,能多啰嗦几句的绝对不能省略·····

对的。。发现我考虑不周全。

 
redmountain:

我也没特别明白你的意思,但是你最后那几行,当然会有“干扰”啊;

反而有“干扰”才是正常的,因为从代码上看你就是想要那样的结果!

否则,应该去掉函数传进去的参数前面的&符号,函数变成

我的确是不想让他们之间干扰,我把&符号去掉以后,提示我 "arrays are passed by reference only"

比如

void zztest_a(double highPrice[],
              double lowPrice[]
             )
  {

  }
这样就无法编译通过。
 
solrv:

我的确是不想让他们之间干扰,我把&符号去掉以后,提示我 "arrays are passed by reference only"

比如

这样就无法编译通过。

的确如你所说,这个是我的失误,抱歉。

我看了之前我写的函数数组也的确用了&符号

虽然是这样,可依然没遇到过你说的复用问题。

那就函数里面不要对其赋值,或者用过程变量提取、存储等操作就好了啊。

 
redmountain:

的确如你所说,这个是我的失误,抱歉。

我看了之前我写的函数数组也的确用了&符号

虽然是这样,可依然没遇到过你说的复用问题。

那就函数里面不要对其赋值,或者用过程变量提取、存储等操作就好了啊。

我也很诧异,其他平台比如mc上类似变成也没有遇到这种,复用函数时出现相互干扰问题。

我觉得问题可能出在,我为了节约计算资源,每次使用static int startBar来记录计算进度。可能是这个函数造成的 在其他函数中 调用相同函数名称时出现109689768797这种得数。

现在我解决的办法是 如果要复用这个函数,就把函数改个名字另存。用另存的名字调用。