Вопросы от "чайника" - страница 126

 
Renat:

А с каких это пор все массивы стали статическими и все индексы и размеры - тоже?

Так как практически всегда массивы динамические, индексы - переменные, то никаких серьезных статических проверок в момент вызова сделать нельзя. Остается делать только проверки на основе метаинформации/rtti и именно поэтому так важно иметь доступ ко всему объекту/описанию, а не работать на авось с куском памяти.

Тэкс.  Давайте по порядку.  Для статических массивов всё легко проверяемо при компиляции, так?

Для динамических (которые есть скрытые объекты!), есть метаинформация в рантайме, так? Есть! Безусловно есть.

Осталось только прописать ран-тайм проверки в исполнимом коде компилируемой функции. И всё!

И я не говорю что это плёвое дело. Ну так и Слава (Stringo) тоже ведь не лыком шит.  И вообще, кому сейчас легко?.. :)

// В конце концов: в четвёрке это всё сделано.

// Если уже сделали динамические массивы, так используйте метаинформацию которую они всюду с собой таскают!

// Имея её можно вообще делать чудесные вещи (типа позволения юзеру передавать массивы неизвестной размерности).

// А у вас в mql5(!) нельзя даже двумерный массив с обоими неизвестными сайздименшнз передать в функцию.

// Даже в антикварной жабе и то можно.. :))

 
Renat:

Не беспокойтесь, все давно продумано.

Последствия нарушения принципов защиты мы отлично знаем - это путь "в апреле исправили еще 12 критических ошибок, позволяющих вырваться за пределы виртуалки и получить контроль над системой".

Я и не беспокоюсь.  Последствия данного конкретного решения, даже не пахнут "контролем над системой". Никаких таких указателей на функции я у вас не просил.  Максимум чем может навредить - это порушить "чужую" память при неправильно проконтролированном выходе за диапазон массива.
 
MetaDriver:

1. Так я и предложил ввести поименование и следовательно жёсткую типизацию.  Тем более, что это единственное место не охваченное именной типизацией, следовательно хорошо вписывается в идеологию универсализации сущностей языка.

2. Тоже делаю. Всё равно: во первых криво, во вторых неуниверсально ни разу. Вот предложите способ (1) копирования двумерного mql-массива в буфер ОпенЦЛ без лишнего переписывания и заворачивания в структуры.  Или (2) использования (в целях скорострельности) вашей же функции ArrayCopy(..) для неодномерных массивов.

// Извините зе резкость предыдущего поста. Действительно излишне. Возбудился на "не будем усложнять". Поскольку как раз ведёт к сложностям.

2а.  Я думаю, что во многих случаях ваше "ограничение на одномерность" для функций подобных ArrayCopy() можно безболезненно ослабить при помощи одной элементарной оговорки в комментах: "Функция работает и с многомерными массивами, при условии, что многомерный массив копируется целиком."

Много проблем бы отпало. // Но не все, конечно.

Тут два пути, один копировать отдельно одномерные массивы, но это не есть гуд, тк OCL интерфейс будет завален массивами,

и второй путь представлять одномерный массив как двумерный, он ведь в OCL всё равно лентой передаётся. Тогда как то так. Кстати сами перемещения данных при изменении размерности можно сделать в OCL через копирование части массива, всё зависит от размеров, насколько это рентабельно.

class CArrayTwo_merniy
  {
   float             a[];
   int               size_i;
   int               size_j;
public:
                     CArrayTwo_merniy(void){size_i=0;size_j=0;};
                    ~CArrayTwo_merniy(void){};
   void              Resize(int i,int j)
     {
      int size;
      if(j<size_j)// если уменьшаем j размер массива
        {
         for(int l=1;l<i;l++)
            for(int k=0;k<j;k++)
               a[l*i+k]=a[l*size_i+k];
         size=ArrayResize(a,i*j);
         if(size==i*j)
           {size_i=i; size_j=j;}
         return;
        }
      else // иначе, если увеличиваем j размер массива
        {
         size=ArrayResize(a,i*j);
         if(size==i*j)
           {
            for(int l=i-1;l>=0;l--)
               for(int k=j-1;k>=0;k--)
                  a[l*i+k]=a[l*size_i+k];
            size_i=i; size_j=j;
           }
        }
     };
   void set(int i,int j,float v)
     {
      if(i*size_i+j>=0 && i*size_i+j<size_i*size_j)a[i*size_i+j]=v;
      else Print("Ошибка set ["+i+":"+j+"]");
     };
   float get(int i,int j)
     {
      if(i*size_i+j>=0 && i*size_i+j<size_i*size_j)return(a[i*size_i+j]);
      else {Print("Ошибка get ["+i+":"+j+"]"); return(EMPTY_VALUE);}
     };
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   CArrayTwo_merniy ar; string t;
   ar.Resize(3,3); int cnt=0;
   for(int i=0;i<3;i++)for(int j=0;j<3;j++){ar.set(i,j,(float)cnt); cnt++;}
   t="исх ";for(int i=0;i<3;i++){for(int j=0;j<3;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
   ar.Resize(5,5);
   t="5х5 "; for(int i=0;i<5;i++){for(int j=0;j<5;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
   ar.Resize(3,3);
   t="3х3 ";for(int i=0;i<3;i++){for(int j=0;j<3;j++)t+="["+ar.get(i,j)+"]";t+=".";} Print(t);
  }
 
Urain:

Тут два пути, один копировать отдельно одномерные массивы, но это не есть гуд, тк OCL интерфейс будет завален массивами,

и второй путь представлять одномерный массив как двумерный, он ведь в OCL всё равно лентой передаётся. Тогда как то так. Кстати сами перемещения данных при изменении размерности можно сделать в OCL через копирование части массива, всё зависит от размеров, насколько это рентабельно.

многа многа букаф

Вот всего этого я как раз и наелся досыта. :)  Оккам бьётся в истерике..

;)

Вот есть у меня двумерный массив. Есть его sizeof(My2DArray). Ну чего ещё надо для копирования в буфер??? Все равно мне никто там даже смещение в моём массиве не предусмотрел переменным сделать. Так нет. Нужно сначала его переписать (что приводит к тормозам), либо написать собственный двумерный массив.  (!!)  Ну зашибись. И зачем это? А чтоб мне безопасно было. (!)  Всё, ржунимагу. :)))

 
MetaDriver:

Вот всего этого я как раз и наелся досыта. :)  Оккам бьётся в истерике..

;)

:))

Да честно говоря накладные расходы по изменению размера огроменные, но применяя OCL для этих дел можно их урезать.

Зато прямое копирование двумерного массива в OCL буффер.

И я бы не советовал переразбивать массив на каждом чихе.

А так вполне применибельно.

 
MetaDriver:

Вот всего этого я как раз и наелся досыта. :)  Оккам бьётся в истерике..

;)

Да ладно тебе многа букаф, три функции set get и Resize

ЗЫ специально для тебя накропал, на коленках, пока ты тут хилосохствувал.

 
Urain:
Да ладно тебе многа букаф, три функции set get и Resize
Ну клёво, кто спорит. Вот ещё когда нам перегрузку операторов сделают (и не забудут при этом операторы "[ ]" и "="сделать перегружаемым, тады ваще лафа. Будем в маркете торговать своими динамическими массивами. И будут брать! А кто не возьмёт - отключим газ передачу многомерных массивов в функции. :)
 
MetaDriver:
Ну клёво, кто спорит. Вот ещё когда нам перегрузку операторов сделают (и не забудут при этом оператор "[ ]" сделать презгужаемым, тады ваше лафа. Будем в маркете торговать своими динамическими массивами. И будут брать! А кто не возьмёт - отключим газ передачу многомерных массивов в функции. :)
Не забудем ;)
 
mql5:
Не забудем ;)
:))
 
MetaDriver:

Вот есть у меня двумерный массив. Есть его sizeof(My2DArray). Ну чего ещё надо для копирования в буфер??? Все равно мне никто там даже смещение в моём массиве не предусмотрел переменным сделать. Так нет. Нужно сначала его переписать (что приводит к тормозам), либо написать собственный двумерный массив.  (!!)  Ну зашибись. И зачем это? А чтоб мне безопасно было. (!)  Всё, ржунимагу. :)))

Уважаемый, следите за контекстом.

1) Когда Вы из одной контролируемой и безопасной среды прыгаете в абсолютно неконтролируемый сырой буфер, то именно Вы отвечаете за совместимость с той бинарной средой.

2) Когда Вы пишите код, то именно Вы отвечаете за архитектуру этого кода. И не надо плакаться, что "трудно впрячь коня и трепетную лань в одну телегу" при использовании разных структур.

3) Рекомендую прочитать описание CLBufferRead и CLBufferWrite - за счет универсальной void* ссылки есть возможность передачи в OpenCL ссылки любого типа. Причем есть и смещения и размеры.

uint  CLBufferRead(
   int          buffer,                    // хендл на буфер OpenCL
   const void&  data[],                     // массив значений
   uint         buffer_offset=0,           // смещение в OpenCL буфере в байтах, по умолчанию 0
   uint         data_offset=0,             // смещение в массиве в элементах, по умолчанию 0
   uint         data_count=WHOLE_ARRAY      // количество значений из буфера для чтения, по умолчанию весь буфер
   );
uint  CLBufferWrite(
   int          buffer,                    // хендл на буфер OpenCL
   const void&  data[],                     // массив значений
   uint         buffer_offset=0,           // смещение в OpenCL буфере в байтах, по умолчанию 0
   uint         data_offset=0,             // смещение в массиве в элементах, по умолчанию 0
   uint         data_count=WHOLE_ARRAY      // количество значений из массива для записи, по умолчанию весь массив
   );

Я вижу, что тема просто высосана из пальца.

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