здравствуйте. вопрос по Си++ (просьба всех атцов в Си++ больно не пинаться): у меня есть двумерный массив байтов #define mapSize 256 BYTE field[mapSize][mapSize]; нужно создать новый такой же по размерам двумерный массив байтов, и заполнить его нужными мне байтами. почему-то не получается сделать это сл обазом: Код (Text): //некоторые переменные long i; long j; float value; float cellAverage; //выделяем память и сохраняем на нее указатель в result //тут почему-то компилер ругается: 'initialization to 'BYTE *' from 'unsigned char '[ * ][ 256 ]' BYTE *result = new BYTE[mapSize][mapSize]; //пробегаемся по всему 2умерном массиву //вычисляем то что нам нужно //и пытаемся загнать это последовательно в новый 2умерный массив result for (i = 0; i<mapSize; ++i) for (j = 0; j<mapSize; ++j) { //считаем что нам нужно value=blahblahh; cellAverage=blablah; //заносим в новый массив нужные данные //тоже ругается: 'invalid types 'unsiged char[long int]' for array subscript' result[i][j] = (BYTE) (value / cellAverage); } //удаляем старый массив delete [] field; //создаем новый field и копируем в него все данные из result'a //опять ругается: 'incompatible types in assignment of 'BYTE *' to 'unsigned char[256][256]' field = result; оформляем сообщения, проявляйте уважение к участникам форума
А так не подойдёт? Код (Text): void *result = malloс (mapSize*mapSize); *((BYTE*)result+i*mapSize+j) = (BYTE) (value / cellAverage); Я конечно не отец С++, но мне кажется использовать new для больших массивов не совсем хорошо.
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.
alpet У меня что-то на BCB6 не рулит такое объявление. Посмотрел в хелпе, тоже про это не сказано.Сработало вот так: Код (Text): typedef BYTE MATRIX[mapSize]; MATRIX *field = new MATRIX[mapSize]; field[i][j] = (BYTE) (value / cellAverage); Полностью согласен. Так что IMHO new и malloc - одно и тоже.
спасибо за пояснения. пост alpetа уяснил. теперь, в продолжение темы: пишу я класс для работы с ландшафтом. естественно, этот класс как минимум содержит поле byteMap нужного типа (допустим BYTE или float) под высоты ландшафта. я пишу функцию-член этого класса для считывания из карты высот (.raw файла) байтовых значений и помещаю их в поле map. тут все хорошо. теперь вот мне в голову приходит мысль о том, что неплохо бы 'пробежаться' по всему полю map и аппроксимировать его значения, дабы придать ландшафту бОльшую сглаженность. но, аппроксимируя элементы из map я скорее всего получу нецелые значения (или же захочу их использовать), т.е. float. получается, что мое старое поле класса map уже не сможет вместить в себя все эти новые float значения, и появляется необходимость в 'заведении' нового 'хранилища' floatMap под эти float элементы, а map становится ненужным полем. конечно, можно сделать класс с 2мя полями-массивами под высоты: byteMap и floatMap; считать из .raw файла высоты в первый массив, аппроксимировать их и записать во второй, сделать delete [] byteMap, а в рендеринге ландшафта использовать значения из floatMap... но как-то неочень красиво получается в этом случае (имею ввиду какую-то чуть ли не никчемность первого массива byteMap). как лучше всего тут поступить и спланировать? уверен, что есть более красивый и естественный способ.
Можно фиксированную точку использовать, 8 бит на целую часть + 8 на дробную. Точности imho хватит и работать будет быстрее. Код (Text): const int mapSize = 256; static unsigned short map[mapSize][mapSize]; unsigned short * p = &map[0][0]; for( int i = 0; i < mapSize * mapSize; ) { p[i++] = read_byte_from_raw_file() * ((1<<8) + 1); } аппроксимировать можно в этом же массиве, и никаких телодвижений с аллокацией памяти
S_T_A_S_ А можно посмотреть на цикл, который это будет делать без дополнительной памяти? Где, к примеру, брать исходные значения из первой строки(для апроксимации второй), после замены их аппроксимированными?
Можно сохранять исходные значения предыдущей строки и предыдущего элемента. Дополнительно массив 256 элементов в стэке + переменная в регистре. Но это от способа апроксимации зависит. В худьшем случае достаточно 2х массивов 256*256, один статический, другой в стэке.
хм, я вот как сделал окончательно: в функции-члене класса по считыванию высот из карты_высот я создаю временный массив целых чисел в памяти, считываю в него высоты, а затем копирую их в отведенный под float высоты массив в классе.