MQL4中二维数组运行异常,报无效索引值错误求助
问题分析与修复
错误原因
- 动态二维数组未初始化:MQL4中声明的
A[][]、tab[][]这类动态二维数组,必须先通过ArrayResize明确指定行数和列数,否则直接访问索引会触发"invalid index value"错误。 - for循环条件错误:所有
for循环的终止条件写法错误,比如for(int i=0; m-1; i++),正确的条件应该是i < m-1,否则循环逻辑完全错误(要么不执行,要么无限循环)。 - 一维动态数组未初始化:
b[]等一维动态数组同样需要先调整大小才能赋值。
修复步骤
- 在
OnInit函数中初始化所有动态数组的大小,根据m和n确定维度:- 二维数组
A行数设为m、列数设为n,执行ArrayResize(A, m, n) - 一维数组
b大小设为m,执行ArrayResize(b, m)
- 二维数组
- 修正所有
for循环的终止条件,将m-1、n这类写法改为i < m-1、j < n - 初始化临时二维数组
tab时,先通过ArrayResize设置行数为m+1、列数为2*m + n + 1(匹配代码中访问的最大索引tab[m][2*m+n]),再进行赋值操作
修复后的完整代码
//+------------------------------------------------------------------+ //| test.mq4 | //| Copyright 2021, MetaQuotes Software Corp. | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict extern int m=30; extern int n=5; int Base_Idx[]; double pt, b[], A[][], PivotColumn[]; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- pt = Point; if (Digits == 3 || Digits == 5) { pt*=10; } // 初始化动态数组大小 ArrayResize(A, m, n); // A为m行n列的二维数组 ArrayResize(b, m); // b为大小m的一维数组 ArrayResize(Base_Idx, m); // 按需初始化Base_Idx ArrayResize(PivotColumn, n); // 按需初始化PivotColumn //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // 初始化A数组为0 for(int i=0; i < m; i++) { for(int j=0; j < n; j++) { A[i][j] = 0; } } //-------------- Matrix A ---------------------- for (int i=0; i < m; i++) { A[i][0] = i + 2; A[i][1] = i + 4; A[i][2] = i + 6; A[i][3] = i + 8; A[i][4] = i + 10; // 防止K线数量不足导致越界 if(i+1 < Bars) { b[i] = Close[i+1]; } } // 初始化tab数组大小 double tab[][]; int tabRows = m + 1; int tabCols = 2 * m + n + 1; ArrayResize(tab, tabRows, tabCols); // 初始化tab为0 for(int i=0; i < tabRows; i++) { for(int j=0; j < tabCols; j++) { tab[i][j] = 0; } } // 复制A到tab for(int i=0; i < m; i++) { for(int j=0; j < n; j++) { tab[i][j] = A[i][j]; } } // 复制b到tab最后一列 for(int i=0; i < m; i++) { tab[i][2*m + n] = b[i]; } // 初始化tab最后一行 for(int j=0; j < tabCols -1; j++) { tab[m][j] = 2; } //+----------------------- Phase One Of SIMPLEX Method ----------------------------+ for(int i=0; i < m; i++) { for(int j=0; j < tabCols; j++) { tab[m][j] -= tab[i][j]; } } return; }
额外注意事项
- 访问
Close[i+1]时必须检查i+1 < Bars,避免因当前图表K线数量不足导致数组越界错误。 - MQL4中所有动态数组使用前必须通过
ArrayResize设置大小,不支持未初始化的动态数组直接赋值。
内容的提问来源于stack exchange,提问作者Arash
相关产品推荐
相关产品推荐

