Проблему с массивом строк не могу понять ...

 
Есть код тестовый:

   string PosComments[];
   int PosCnt = 3;
   if(ArraySize(PosComments) < PosCnt) {
      ArrayResize(PosComments, PosCnt);
      for(p = 0; p < PosCnt; p++) {
         if(StringLen(PosComments[p]) > 0) continue;
         for(i = 0; i < 18; i++) PosComments[p] = PosComments[p] + "z";
      }      
      Print(PosComments[0]);   
      Print(PosComments[1]);   
      Print(PosComments[2]);   
   }

выводит результат
23:47:39 MTMutComm EURUSD,M1: zzzzzzzzzzzzzzzzzz
23:47:39 MTMutComm EURUSD,M1: zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
23:47:39 MTMutComm EURUSD,M1: zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
а хотелось бы
23:47:39 MTMutComm EURUSD,M1: zzzzzzzzzzzzzzzzzz
23:47:39 MTMutComm EURUSD,M1: zzzzzzzzzzzzzzzzzz
23:47:39 MTMutComm EURUSD,M1: zzzzzzzzzzzzzzzzzz

Может быть укажете на ошибку в коде? Или может быть ошибка в самом MQL4

 
Это в 211 билде? Будем разбираться.
Спасибо за пример.
 

Да терминал AlpariUK Version 4 Buld 211 (15 October 2007)

Но вы попробуйте у себя

 

причем на первой итерации шарашится 18 зедов, а на последующих по 17

 

PosComments[p] + "z"

д.б.

PosComments[p] = StringConcatenate(PosComments[p],"z")

Вобчем таже же ж.. (ой!) засада,что и с даблами. Для верности надо использовать StringConcatenate, а не +

 

Да с  StringConcatenate я тоже пробовал и даже если напрямую присваивать 18 - z элементу массива

Причём проверял в длл что именно каждый элемента массива PosComments соответсвует тому что выводит Print(PosComments[i]). Там что подозрение не оправдалось, что Print выводит и все элементы до i-го элемента и сам i-ый элемент включительно.

При этом сначало то как и должно быть длинная строки в каждом элементе массива равно 0

if(StringLen(PosComments[p]) > 0) continue;

 
Мне Слава раньше часто говорил (и это написано практически во всех книгах по программированию):"Никогда не полагайся на значения по умолчанию, всегда самостоятельно инициализируй переменные и массивы". Это как раз этот случай. Если самому инициализировать значения элементов массива пустым значением "", то таких эффектов не наблюдается.

//+------------------------------------------------------------------+
//|                                             CheckStringArray.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
#property show_inputs
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   string PosComments[];
   int i,p,PosCnt = 3;
   if(ArraySize(PosComments)<PosCnt) 
      {
      Print("ArraySize(PosComments)=",ArraySize(PosComments));
      ArrayResize(PosComments, PosCnt);
      for(p = 0; p < PosCnt; p++) 
         {
              PosComments[p]="";//  явная инициализация
         Print("PosComments[",p,"]=",PosComments[p],"|");
         if(StringLen(PosComments[p]) > 0) continue;
         for(i = 0; i < 18; i++) 
            {
            Print("i=",i," PosComments[",p,"]=",PosComments[p]);
            PosComments[p] = PosComments[p] + "z";
            }
         }      
      Print(PosComments[0]);   
      Print(PosComments[1]);   
      Print(PosComments[2]);   
      }
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
Вот результат работы скрипта:

11:42:47 CheckStringArray EURUSD,H1: loaded successfully
11:43:00 CheckStringArray EURUSD,H1: ArraySize(PosComments)=0
11:43:00 CheckStringArray EURUSD,H1: PosComments[0]=|
11:43:00 CheckStringArray EURUSD,H1: i=0 PosComments[0]=
11:43:00 CheckStringArray EURUSD,H1: i=1 PosComments[0]=z
11:43:00 CheckStringArray EURUSD,H1: i=2 PosComments[0]=zz
11:43:00 CheckStringArray EURUSD,H1: i=3 PosComments[0]=zzz
11:43:00 CheckStringArray EURUSD,H1: i=4 PosComments[0]=zzzz
11:43:00 CheckStringArray EURUSD,H1: i=5 PosComments[0]=zzzzz
11:43:00 CheckStringArray EURUSD,H1: i=6 PosComments[0]=zzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=7 PosComments[0]=zzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=8 PosComments[0]=zzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=9 PosComments[0]=zzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=10 PosComments[0]=zzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=11 PosComments[0]=zzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=12 PosComments[0]=zzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=13 PosComments[0]=zzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=14 PosComments[0]=zzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=15 PosComments[0]=zzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=16 PosComments[0]=zzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=17 PosComments[0]=zzzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: PosComments[1]=|
11:43:00 CheckStringArray EURUSD,H1: i=0 PosComments[1]=
11:43:00 CheckStringArray EURUSD,H1: i=1 PosComments[1]=z
11:43:00 CheckStringArray EURUSD,H1: i=2 PosComments[1]=zz
11:43:00 CheckStringArray EURUSD,H1: i=3 PosComments[1]=zzz
11:43:00 CheckStringArray EURUSD,H1: i=4 PosComments[1]=zzzz
11:43:00 CheckStringArray EURUSD,H1: i=5 PosComments[1]=zzzzz
11:43:00 CheckStringArray EURUSD,H1: i=6 PosComments[1]=zzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=7 PosComments[1]=zzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=8 PosComments[1]=zzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=9 PosComments[1]=zzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=10 PosComments[1]=zzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=11 PosComments[1]=zzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=12 PosComments[1]=zzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=13 PosComments[1]=zzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=14 PosComments[1]=zzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=15 PosComments[1]=zzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=16 PosComments[1]=zzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=17 PosComments[1]=zzzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: PosComments[2]=|
11:43:00 CheckStringArray EURUSD,H1: i=0 PosComments[2]=
11:43:00 CheckStringArray EURUSD,H1: i=1 PosComments[2]=z
11:43:00 CheckStringArray EURUSD,H1: i=2 PosComments[2]=zz
11:43:00 CheckStringArray EURUSD,H1: i=3 PosComments[2]=zzz
11:43:00 CheckStringArray EURUSD,H1: i=4 PosComments[2]=zzzz
11:43:00 CheckStringArray EURUSD,H1: i=5 PosComments[2]=zzzzz
11:43:00 CheckStringArray EURUSD,H1: i=6 PosComments[2]=zzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=7 PosComments[2]=zzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=8 PosComments[2]=zzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=9 PosComments[2]=zzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=10 PosComments[2]=zzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=11 PosComments[2]=zzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=12 PosComments[2]=zzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=13 PosComments[2]=zzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=14 PosComments[2]=zzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=15 PosComments[2]=zzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=16 PosComments[2]=zzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: i=17 PosComments[2]=zzzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: zzzzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: zzzzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: zzzzzzzzzzzzzzzzzz
11:43:00 CheckStringArray EURUSD,H1: uninit reason 0
11:43:00 CheckStringArray EURUSD,H1: removed



Пусть даже данную ошибку компилятора исправят, но на будущее, независимо от того на каком языке и в какой среде будете писать программу - всегда делайте янвную инициализацию.
 
Rosh:
...Никогда не полагайся на значения по умолчанию, всегда самостоятельно инициализируй переменные и массивы...


Отличная мысль.

Надо прилепить ее в голове форума :). А было бы здОрово, если бы нашелся энтузиаст, и оформил подобные нетленки в виде фака.

Эта мысль у меня всегда подспудно крутилась в голове, когда приходилось программить. Всегда вспоминал старика Мюллера: "Никому верить нельзя. Мне - можно. Хе-хе." К сожалению, нельзя верить ни-ко-му.

Еще одно наблюдения. Я третьего дня поднимал аналогичный вопрос, но в более общем виде: Как определить пустую строковую переменную? Были предложены решения выхода из этой ситуации (спасибо откливнушимся), но вопрос так и остался открытым. Поскольку остальные не придали значения обсуждению (как разработчики, так и тредстартер, пока его тот же петух в то ж-ж-е место не клюнул ;), я пользуюсь случаем спросить авторитетного мнения Rosh'а:

Применительно к моему траблу. Понятно, что принудительная инициализация снимает большинство вопросов. Если это делается на уровне init() - быстродействие пофиг. Но как быть, если в start() при обработке каждого тика в цикле приходится постоянно обновлять большой массив? Если это делать поэлементно - получаются такие большие затраты времени. И именно из-за того, что не реализована процедура корректной инициализации строковых переменных, о чем разработчики скромно молчат.

Как с этим траблом будет обстоять дело в текущих релизах четверки и ожидающемся MQL5?

Решение, конечно, найдено. Паллиатив, но работает. Хотелось бы, как малоопытному программисту, брать на вооружение в первую очередь стандартные, а не альтернативные, суррогатные (это не такое плохое слово, как можно подумать) решения. Начинающему (повторяю) очень тяжело ориентироваться в подобных нештатных ситуациях, когда подводный камень кроется в самой, казалось, тривиальной ситуации. Я понимаю, что это учебка в боевых условиях. Но слишком дорого может быть получен этот опыт.

 
Chen:

Применительно к моему траблу. Понятно, что принудительная инициализация снимает большинство вопросов. Если это делается на уровне init() - быстродействие пофиг. Но как быть, если в start() при обработке каждого тика в цикле приходится постоянно обновлять большой массив? Если это делать поэлементно - получаются такие большие затраты времени. И именно из-за того, что не реализована процедура корректной инициализации строковых переменных, о чем разработчики скромно молчат.

Проверьте самостоятельно и Вы убедитесь, что принудительная инициализация требует на несколько порядков меньше времени, чем увеличение размера массива функцией ArrayResize(). Если Вы хотите получить максимальное быстродействие при тестировании, то старайтесь избегать использование Global Varuables и задавайте сразу достаточно большой размер служебного массива (это касается случаев, когда возможны десятки и сотни тысяч операций увеличения размера массива).
 
Chen:

Еще одно наблюдения. Я третьего дня поднимал аналогичный вопрос, но в более общем виде: Как определить пустую строковую переменную? Были предложены решения выхода из этой ситуации (спасибо откливнушимся), но вопрос так и остался открытым. Поскольку остальные не придали значения обсуждению (как разработчики, так и тредстартер, пока его тот же петух в то ж-ж-е место не клюнул ;), я пользуюсь случаем спросить авторитетного мнения Rosh'а:

Я не силен в Си, и траблы с передачей строковых переменных в dll не могу объяснить. Сам как-то наступал на такие грабли (Crash в "About"). Хотя с тех пор я лучше представляю механизм распределения памяти под переменные, но давать советы и решения все же не берусь.
 
Rosh:
Chen:

Применительно к моему траблу. Понятно, что принудительная инициализация снимает большинство вопросов. Если это делается на уровне init() - быстродействие пофиг. Но как быть, если в start() при обработке каждого тика в цикле приходится постоянно обновлять большой массив? Если это делать поэлементно - получаются такие большие затраты времени. И именно из-за того, что не реализована процедура корректной инициализации строковых переменных, о чем разработчики скромно молчат.

Проверьте самостоятельно и Вы убедитесь, что принудительная инициализация требует на несколько порядков меньше времени, чем увеличение размера массива функцией ArrayResize(). Если Вы хотите получить максимальное быстродействие при тестировании, то старайтесь избегать использование Global Varuables и задавайте сразу достаточно большой размер служебного массива (это касается случаев, когда возможны десятки и сотни тысяч операций увеличения размера массива).


ОК. Спасибо за очередные интересные подсказки. Возьму на заметку. Я, конечно, проверю, но Вам я склонен доверять. Как Мюллеру :)

Значит моя посылка, что функция ArrayResize() будет эффективнее поэлементной инициализации просто неверна. ..

Причина обращения: