Си++ : непонятка с созданием 2умерного массива

Тема в разделе "WASM.ZEN", создана пользователем varnie, 6 авг 2005.

  1. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    здравствуйте.

    вопрос по Си++ (просьба всех атцов в Си++ больно не пинаться):

    у меня есть двумерный массив байтов

    #define mapSize 256

    BYTE field[mapSize][mapSize];

    нужно создать новый такой же по размерам двумерный массив байтов, и заполнить его нужными мне байтами.

    почему-то не получается сделать это сл обазом:
    Код (Text):
    1. //некоторые переменные
    2. long i;
    3. long j;
    4. float value;
    5. float cellAverage;
    6.  
    7. //выделяем память и сохраняем на нее указатель в result
    8. //тут почему-то компилер ругается: 'initialization to 'BYTE *' from 'unsigned char '[ * ][ 256 ]'
    9. BYTE *result = new BYTE[mapSize][mapSize];
    10.  
    11. //пробегаемся по всему 2умерном массиву
    12. //вычисляем то что нам нужно
    13. //и пытаемся загнать это последовательно в новый 2умерный массив result
    14.  for (i = 0; i<mapSize; ++i)
    15.   for (j = 0; j<mapSize; ++j)
    16.   {
    17.     //считаем что нам нужно
    18.     value=blahblahh;
    19.     cellAverage=blablah;  
    20.  
    21.     //заносим в новый массив нужные данные
    22.     //тоже ругается: 'invalid types 'unsiged char[long int]' for array subscript'
    23.     result[i][j] = (BYTE) (value / cellAverage);
    24.   }
    25.  
    26. //удаляем старый массив
    27. delete [] field;
    28.  
    29. //создаем новый field и копируем в него все данные из result'a
    30. //опять ругается: 'incompatible types in assignment of 'BYTE *' to 'unsigned char[256][256]'
    31. field = result;
    оформляем сообщения, проявляйте уважение к участникам форума
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А так не подойдёт?
    Код (Text):
    1. void *result = malloс (mapSize*mapSize);
    2. *((BYTE*)result+i*mapSize+j) = (BYTE) (value / cellAverage);


    Я конечно не отец С++, но мне кажется использовать new для больших массивов не совсем хорошо.
     
  3. alpet

    alpet Александр

    Публикаций:
    0
    Регистрация:
    21 сен 2004
    Сообщения:
    1.221
    Адрес:
    Russia
    varnie

    Строкой BYTE* result, ты определяешь указатель на байт, или набор байтов. Компилятор представления не имеет, какую может иметь размерность эта переменная в представлении двух мерного массива (и указанные параметры оператора new ему здесь не помошник). По этому если уж ты так ее определил, изволь работать как с одномерным массивом:

    result[i * mapSize + j] = (BYTE) (value / cellAverage);



    Либо попробуй так:

    typedef BYTE[mapSize][mapSize] MATRIX;

    typedef MATRIX* PMATRIX;

    *((PMATRIX) result) [j] = (BYTE) (value / cellAverage);



    booster

    64k = вполне нормальный размер для использования кучи и оператора new в частности. Вот когда размер приближается к мегабайту, уже уместно использовать VirtualAlloc.
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    alpet



    У меня что-то на BCB6 не рулит такое объявление. Посмотрел в хелпе, тоже про это не сказано.Сработало вот так:
    Код (Text):
    1. typedef BYTE MATRIX[mapSize];
    2. MATRIX *field = new MATRIX[mapSize];
    3. field[i][j] = (BYTE) (value / cellAverage);




    Полностью согласен.



    Так что IMHO new и malloc - одно и тоже.
     
  5. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347




    BYTE *result = new BYTE[mapSize*mapSize];
     
  6. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Booster



    А использовать malloc в C++ совсем не хорошо :)
     
  7. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    спасибо за пояснения. пост alpetа уяснил.

    теперь, в продолжение темы:

    пишу я класс для работы с ландшафтом. естественно, этот класс как минимум содержит поле byteMap нужного типа (допустим BYTE или float) под высоты ландшафта. я пишу функцию-член этого класса для считывания из карты высот (.raw файла) байтовых значений и помещаю их в поле map.

    тут все хорошо.

    теперь вот мне в голову приходит мысль о том, что неплохо бы 'пробежаться' по всему полю map и аппроксимировать его значения, дабы придать ландшафту бОльшую сглаженность. но, аппроксимируя элементы из map я скорее всего получу нецелые значения (или же захочу их использовать), т.е. float.

    получается, что мое старое поле класса map уже не сможет вместить в себя все эти новые float значения, и появляется необходимость в 'заведении' нового 'хранилища' floatMap под эти float элементы, а map становится ненужным полем.

    конечно, можно сделать класс с 2мя полями-массивами под высоты: byteMap и floatMap; считать из .raw файла высоты в первый массив, аппроксимировать их и записать во второй,

    сделать delete [] byteMap, а в рендеринге ландшафта использовать значения из floatMap...

    но как-то неочень красиво получается в этом случае (имею ввиду какую-то чуть ли не никчемность первого массива byteMap).

    как лучше всего тут поступить и спланировать? уверен, что есть более красивый и естественный способ.
     
  8. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Можно фиксированную точку использовать, 8 бит на целую часть + 8 на дробную. Точности imho хватит и работать будет быстрее.
    Код (Text):
    1. const int mapSize = 256;
    2. static unsigned short map[mapSize][mapSize];
    3. unsigned short * p = &map[0][0];
    4. for( int i = 0; i < mapSize * mapSize; )
    5. {
    6.     p[i++] = read_byte_from_raw_file() * ((1<<8) + 1);
    7. }
    аппроксимировать можно в этом же массиве, и никаких телодвижений с аллокацией памяти :derisive:
     
  9. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    S_T_A_S_





    А можно посмотреть на цикл, который это будет делать без дополнительной памяти? Где, к примеру, брать исходные значения из первой строки(для апроксимации второй), после замены их аппроксимированными?
     
  10. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Можно сохранять исходные значения предыдущей строки и предыдущего элемента. Дополнительно массив 256 элементов в стэке + переменная в регистре. Но это от способа апроксимации зависит. В худьшем случае достаточно 2х массивов 256*256, один статический, другой в стэке.
     
  11. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    хм, я вот как сделал окончательно:

    в функции-члене класса по считыванию высот из карты_высот я создаю временный массив целых чисел в памяти, считываю в него высоты, а затем копирую их в отведенный под float высоты массив в классе.