1

バッファを作成するときにプログラムを配列からベクトルに切り替えるという最近の変更で、まったく関係のない問題が表面化しました。この切り替えには、std::vector<std::vector<std::vector<GLfloat> > > terrainMap;ではなく の作成が含まれGLfloat[size+1][size+1][4] terrainMapます。3 次元ベクトルを初期化するには、次を使用します。

 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;
} 

この時点で、bmp は適切な 1600 x 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 の内容が読み取り不能なメモリを指している場所に移動します。奇妙に感じるのは、3 次元配列を 3 次元ベクトルに変更すると、この問題がどのように発生するかということです。2 つの間の相互作用は発生していません。どんな助けでも大歓迎です。ベヘミス

4

1 に答える 1

0

ピクセルデータを連続したバッファに保持する必要があります。つまり、ベクトルのベクトルではなく、サイズの1 つが必要です。 std::vector<GLfloat>_width * _height * _format

配列の代わりに使用vectorしても、インデックス演算からは解放されません。Ed S.がコメントで指摘したようなメモリリークからあなたを救います。また、コンパイラが提供するデフォルトのコピー代入 (および移動代入) 演算子がうまく機能するため、代入演算子を完全に取り除くことができます。

于 2013-05-19T04:32:49.027 に答える