我正在尝试做最简单的事情,但出现“vector 下标超出范围”错误!我不明白为什么,因为我检查以确保不会发生这种情况。它出现的唯一函数是 addTexture
函数。
纹理库.h
#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;
};
纹理库.cpp
#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;
}
}
}
最佳答案
罪魁祸首很可能是这个陈述:
if (location > textures.size() - 1) {
textures.size()
将是无符号整数类型,并且 location
是一个 int
.在大于比较之前,usual arithmetic conversions将被应用,这意味着 location
将被转换为相同的无符号整数类型。
如果textures
是空的 location
为零,textures.size() - 1
将产生该无符号类型的最大值,比较将产生 false
. textures
不会调整大小,您将尝试访问空 vector
的第零个元素,导致异常。
您可以通过将其修改为轻松修复条件
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
, 确保你的类(class)遵循 Rule of Three .而不是使用
Dispose()
函数等,您最好创建小型 RAII 包装器来处理需要内存管理的 OpenGL 类型。
关于c++ - 为什么我得到 'vector subscript out of range' ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26683720/