2013-05-18 1 views
1

В недавнем изменении, чтобы переключить мою программу с использования массивов в векторы при создании буфера, возникла совершенно не связанная с этим проблема. Этот переключатель включает в себя создание std::vector<std::vector<std::vector<GLfloat> > > terrainMap; вместо GLfloat[size+1][size+1][4] terrainMap. Для того, чтобы инициализировать вектор 3-D, я используюРазрывы загрузки битмапа при переключении в векторы по массивам

terrainMap.resize(size+1); 
for (int i = 0; i < size+1; ++i) { 
    terrainMap[i].resize(size+1); 

    for (int j = 0; j < size+1; ++j) 
     terrainMap[i][j].resize(4); 
    } 

Эта «карта» является параметром многих классов, которые изменяют содержимое как настройки для программы через void Terrain::Load(std::vector<std::vector<std::vector<GLfloat> > >& terrainMap,State &current){ Это странное, хотя, при создании совершенно не связаны растровое изображение для текстурирования, точка брызга попадает и идет дальше, приводит к повреждению кучи. Вот код для загрузки изображения.

bmp = LoadBmp("dirt.jpg"); 

, который проходит в ...

Bitmap Object::LoadBmp(const char* filename) { 
Bitmap bmp = Bitmap::bitmapFromFile(ResourcePath(filename)); 
bmp.flipVertically(); 
return bmp; 
} 

в этой точке ВМР является правильное 1600 по 1600 размер в правильном формате, RGB. Однако, это приводит к неисправности.

Bitmap& Bitmap::operator = (const Bitmap& other) { 
_set(other._width, other._height, other._format, other._pixels); 
return *this; 
} 


void Bitmap::_set(unsigned width, 
       unsigned height, 
       Format format, 
       const unsigned char* pixels) 
{ 
if(width == 0) throw std::runtime_error("Zero width bitmap"); 
if(height == 0) throw std::runtime_error("Zero height bitmap"); 
if(format <= 0 || format > 4) throw std::runtime_error("Invalid bitmap format"); 

_width = width; 
_height = height; 
_format = format; 

size_t newSize = _width * _height * _format; 
if(_pixels){ 
    _pixels = (unsigned char*)realloc(_pixels, newSize); 
} else { 
    _pixels = (unsigned char*)malloc(newSize); 
} 

if(pixels) 
    memcpy(_pixels, pixels, newSize); 
} 

изображение находит свой путь к _pixels = (unsigned char*)realloc(_pixels, newSize); где содержание _pixels указывает на нечитаемым памяти. Что меня удивило, так это то, как изменение трехмерного массива на трехмерный вектор вызывает эту проблему. Никакого взаимодействия между ними не происходит. Буду признателен за любую оказанную помощь. Behemyth

+2

Как насчет предоставления классов * определений *, а не только трехмерного вектора. [SSCCE] (http://www.sscce.org) действительно пригодится. Кроме того, этот трехцветный вектор, безусловно, НЕ будет хранить все выделения в одном непрерывном блоке, поэтому любые мысли, которые вы можете читать или писать, как будто бы это будут * не * работать. Наконец, существует ли твердое конструктор-определение, которое гарантирует, что '_pixels' является NULL, когда оно связано с неинициализированным или нулевым размером растрового изображения? Если нет, вы вызываете 'realloc()' с фиктивным указателем. Если это так, сам тест бессмысленен; realloc() будет корректно работать с NULL. – WhozCraig

+0

Ваш вызов 'realloc' неверен. Если 'realloc' терпит неудачу, у вас есть утечка памяти, потому что вы потеряли исходный указатель. Назначьте возвращаемое значение переменной temp, проверьте значение NULL и присвойте '_pixels'. –

ответ

0

Вы должны держать пиксельные данные в смежный буфер, это означает, что вы должны иметь одинstd::vector<GLfloat> размера _width * _height * _format, а не векторы векторов.

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