【问题标题】:Bitmap Loading Breaks When Switching to Vectors over Arrays在数组上切换到矢量时位图加载中断
【发布时间】:2013-05-13 15:57:34
【问题描述】:

最近在创建缓冲区时将我的程序从使用数组切换到向量的更改中,出现了一个完全不相关的问题。此切换涉及创建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&lt;std::vector&lt;std::vector&lt;GLfloat&gt; &gt; &gt;&amp; terrainMap,State &amp;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-D 数组更改为 3-D 向量是如何导致此问题的。两者之间没有发生任何交互。任何帮助深表感谢。 巨兽

【问题讨论】:

  • 如何提供类 定义 而不仅仅是三维向量。 SSCCE 真的会派上用场。此外,这个三维向量肯定不会将所有分配存储在一个连续的块中,因此您可以读取或写入的任何想法,就好像它不会起作用。最后,当_pixels 与未初始化或大小为零的位图相关联时,是否有可靠的构造函数定义确保为 NULL?如果没有,您将使用虚假指针调用realloc()。如果是这样,测试本身是没有意义的; realloc() 将正确使用 NULL。
  • 您对realloc 的调用是错误的。如果realloc 失败,则表示内存泄漏,因为您丢失了原始指针。将返回值分配给 temp,检查 NULL,然后分配给 _pixels

标签: c++ arrays image vector


【解决方案1】:

您需要将像素数据保存在一个连续的缓冲区中,这意味着您需要 一个 std::vector&lt;GLfloat&gt; 大小为 _width * _height * _format 而不是向量。

使用vector 代替数组不会使您免于索引运算。它将使您免于像 Ed S. 在评论中指出的那样的内存泄漏。而且它可以让你完全摆脱你的赋值操作符,因为编译器提供的默认复制赋值(和移动赋值)操作符会很好用。

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 2020-07-11
    • 2011-08-19
    • 2011-05-16
    • 1970-01-01
    • 2019-11-30
    相关资源
    最近更新 更多