我试图做最简单的事情,但我得到了一个超出范围的'矢量下标'错误!我不明白为什么,因为我检查确保没有发生。它出现的唯一功能是addTexture
。
#pragma once
#include "Disposable.h"
#include "Texture.h"
#include <vector>
class TextureBank: public Disposable
{
public:
TextureBank();
~TextureBank();
virtual void dispose();
void addTexture(int location, Texture *tex);
Texture *getTexture(int location);
private:
std::vector<Texture*> textures;
};
#include "TextureBank.h"
TextureBank::TextureBank()
{
}
void TextureBank::dispose() {
for each (Texture* tex in textures)
{
if (tex != nullptr) {
tex->dispose();
}
}
}
void TextureBank::addTexture(int location, Texture *tex) {
if (location > textures.size() - 1) {
textures.resize(location + 1, nullptr);
}
textures[location] = tex;
}
Texture *TextureBank::getTexture(int location) {
return textures[location];
}
TextureBank::~TextureBank()
{
for each (Texture* tex in textures)
{
if (tex != nullptr) {
delete tex;
}
}
}
答案 0 :(得分:5)
罪魁祸首很可能是这句话:
if (location > textures.size() - 1) {
textures.size()
将是无符号整数类型,location
是int
。在大于比较之前,将应用usual arithmetic conversions,这意味着location
将转换为相同的无符号整数类型。
如果textures
为空并且location
为零,textures.size() - 1
将导致该无符号类型的最大值,并且比较将产生false
。 textures
将不会调整大小,您将尝试访问空vector
的第0个元素,从而导致异常。
您可以通过将条件修改为
来轻松修复条件if (location >= textures.size()) {
如果不能为负,也可以考虑将location
设为无符号类型;并提高编译器的警告级别并注意警告!
您还应考虑进行其他一些更改:
for each (Texture* tex in textures)
是一些非标准的编译器扩展。如果可能,您应该使用基于for
的范围替换它 - for(auto tex : textures)
不要在textures
中存储原始拥有指针,而是考虑将类型更改为std::vector<std::unique_ptr<Texture>>
。然后,您不必在析构函数中明确delete
每个纹理。
如果您无法使用unique_ptr
,请确保您的课程遵循Rule of Three。
除了使用Dispose()
函数之外,最好还是创建小型RAII包装来处理需要内存管理的OpenGL类型。