为什么在向量中的shared_ptr上调用方法会抛出运行时异常?

时间:2016-07-03 11:00:19

标签: c++ shared-ptr runtimeexception

为什么以下代码抛出

Exception thrown at 0x53A5C6DC (nvoglv32.dll) in RenderEngine.exe: 0xC0000005: Access violation reading location 0x0002B174.

在运行时什么是一个好的解决方案?

std::vector<std::shared_ptr<Static>> statics;

void drawStatics() {
    for (std::shared_ptr<Static> stat: statics) {
        Static *statptr = stat.get();

        statptr->Draw(); //This is what triggers the runtime exception.
    }
}

void addStatic(Mesh &mesh, Texture &texture, Transform transform) {
    statics.push_back(
        std::make_shared<Static>(
            mesh,
            texture,
            transform,
            shader,
            camera
        ));
}

int main() {
    addStatic(playerMesh, playerTexture, platformTransform);
    drawStatics();

    return 0;
}

静态头文件如下:

#pragma once

#include "mesh.h"
#include "texture.h"
#include "transform.h"
#include "camera.h"
#include "shader.h"

class Static {
public:
    Static(Mesh &mesh, Texture &texture, Transform &transform, Shader &shader, Camera &camera);
    ~Static();

    void Draw();

private:
    Mesh *mesh;
    Texture *texture;
    Transform *transform;
    Shader *shader;
    Camera *camera;
};

在静态源文件中,Draw()实现为:

void Static::Draw() {
    texture->Bind(0);
    shader->Update(*transform, *camera);
    mesh->Draw();
}

按要求提供静态构造函数和解构函数:

Static::Static(Mesh &mesh, Texture &texture, Transform &transform, Shader &shader, Camera &camera)
    :mesh(&mesh), texture(&texture), transform(&transform), shader(&shader), camera(&camera)
{}

Static::~Static() {}

编辑: 如果重要,我正在使用视觉工作室。

1 个答案:

答案 0 :(得分:5)

这就是你从你的代码中抛出指针和引用而不考虑生命周期所得到的。

Transform

您按 std::make_shared<Static>( mesh, texture, transform, shader, camera )); Static::Static(Mesh &mesh, Texture &texture, Transform &transform, Shader &shader, Camera &camera) :mesh(&mesh), texture(&texture), transform(&transform), shader(&shader), camera(&camera) {} 取值,这意味着它会被复制,因此该函数有自己的实例。

Static::Static

将对局部变量的引用传递给addStatic,获取它的指针并存储指针。 Transform返回,本地Transform*被破坏,你最终会在你的Static *statptr = stat.get(); statptr->Draw(); 中找到一个空闲的内存块指针。

不确定你的其他指针,但你把所有东西作为参考,所以请检查,当它们将被销毁时,其他指针也可能指向free'd空间。

顺便说一下:

get()

您不需要stat->Draw(); 指针。 C ++的智能指针(几乎)表现得像原始指针一样,所以

{{1}}

作品。