在3D渲染应用程序上工作时,用于管理3D纹理的类在调用类析构函数时会引发double free or corruption (!prev)
错误。
我一直在浏览有关同一问题的类似问题,但是没有一个问题能够解决我的问题,因为大多数问题都是基于释放相同内存的两倍。正如我将在下面的代码中显示的那样,这是我已经处理的事情(即使是通过复制构造函数)。
该类本身是以下
Texture3D::Texture3D()
: _width(0)
, _height(0)
, _depth(0)
, _data(nullptr)
, _textureId(GL_INVALID_VALUE)
{
}
Texture3D::Texture3D(const uint width_,
const uint height_,
const uint depth_)
: _width(width_)
, _height(height_)
, _depth(depth_)
, _data(nullptr)
, _textureId(GL_INVALID_VALUE)
{
if(_width > 0 && _height > 0 && _depth > 0)
{
_data = new byte[_width * _height * _depth]();
}
else
{
throw std::runtime_error("Texture3D: zero or negative dimensions specified");
}
}
Texture3D::Texture3D(const byte * data_,
const uint width_,
const uint height_,
const uint depth_)
: Texture3D(width_, height_, depth_)
{
if(data_ != nullptr)
{
std::memcpy(_data, data_, width_ * height_ * depth_);
}
}
Texture3D::Texture3D(const Texture3D & other_)
: _width(other_._width)
, _height(other_._height)
, _depth(other_._depth)
, _data(nullptr)
, _textureId(other_._textureId)
{
if(_width > 0 && _height > 0 && _depth > 0)
{
_data = new byte[_width * _height * _depth]();
}
else
{
throw std::runtime_error("Texture3D: zero or negative dimensions specified");
}
if(other_._data != nullptr)
{
std::memcpy(_data, other_._data, _width * _height * _depth);
}
}
Texture3D::~Texture3D()
{
destroy();
}
byte * Texture3D::getTextureData()
{
return _data;
}
uint Texture3D::getWidth()
{
return _width;
}
uint Texture3D::getHeight()
{
return _height;
}
uint Texture3D::getDepth()
{
return _depth;
}
void Texture3D::setValue(const uint iRow_,
const uint jColumn_,
const uint kDepth_,
const byte value_)
{
if(_checkBounds(iRow_, jColumn_, kDepth_))
{
const uint frameSize = _width * _height;
uint index = kDepth_ * frameSize + jColumn_ * _width + iRow_;
_data[index] = value_;
}
else
{
throw std::runtime_error("Texture3D::setValue: one or more out of bounds indices passed");
}
}
byte Texture3D::getValue(const uint iRow_,
const uint jColumn_,
const uint kDepth_)
{
if(_checkBounds(iRow_, jColumn_, kDepth_))
{
const uint frameSize = _width * _height;
uint index = kDepth_ * frameSize + jColumn_ * _width + iRow_;
return _data[index];
}
else
{
throw std::runtime_error("Texture3D::getValue: one or more out of bounds indices passed");
}
return 0;
}
void Texture3D::upload()
{
glGenTextures(1, &_textureId);
glBindTexture(GL_TEXTURE_3D, _textureId);
glTexStorage3D(GL_TEXTURE_3D, 6, GL_R8, _width, _height, _depth);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, _width, _height, _depth, 0, GL_RED, GL_UNSIGNED_BYTE, _data);
glGenerateMipmap(GL_TEXTURE_3D);
}
void Texture3D::destroy()
{
if(_textureId != GL_INVALID_VALUE)
{
glDeleteTextures(1, &_textureId);
_textureId = GL_INVALID_VALUE;
}
if(_data != nullptr)
{
delete[] _data;
_data = nullptr;
}
}
uint Texture3D::getTextureId()
{
return _textureId;
}
uint Texture3D::getTextureId() const
{
return _textureId;
}
inline bool Texture3D::_checkBounds(const uint i_,
const uint j_,
const uint k_)
{
return i_ < _width && j_ < _height && k_ < _depth;
}
在析构函数中引发错误,该析构函数调用函数destroy()
void Texture3D::destroy()
{
if(_textureId != GL_INVALID_VALUE)
{
glDeleteTextures(1, &_textureId);
_textureId = GL_INVALID_VALUE;
}
if(_data != nullptr)
{
delete[] _data;
_data = nullptr;
}
}
如果我注释delete[] _data;
行,则错误消失。但是,正如您可能理解的那样,如果销毁对象,我不想保留已分配的内存。
我知道我可以/应该使用智能指针或类向量,但是在这一点上,我想知道为什么会抛出错误,当我在删除指针之前确保指针有效并将其设置为nullptr时释放后。您也可以在复制构造函数中看到,我不复制指针本身,而是为源对象分配新的内存并复制内容(如果源对象的指针有效)。
我忘记做某事,还是在代码中没有看到任何错误?
注意:
uint
是typedef unsigned int uint;
byte
是typedef unsigned
char byte;