为什么我得到'矢量下标超出范围'?

时间:2014-10-31 21:33:28

标签: c++ opengl

我试图做最简单的事情,但我得到了一个超出范围的'矢量下标'错误!我不明白为什么,因为我检查确保没有发生。它出现的唯一功能是addTexture

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

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

1 个答案:

答案 0 :(得分:5)

罪魁祸首很可能是这句话:

if (location > textures.size() - 1) {

textures.size()将是无符号整数类型,locationint。在大于比较之前,将应用usual arithmetic conversions,这意味着location将转换为相同的无符号整数类型。

如果textures为空并且location为零,textures.size() - 1将导致该无符号类型的最大值,并且比较将产生falsetextures将不会调整大小,您将尝试访问空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类型。