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

Why does calling a method on a shared_ptr in a vector throw a runtime exception?

本文关键字:方法 运行时 异常 调用 vector 中的 shared ptr 为什么      更新时间:2023-10-16

为什么下面的代码会抛出

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

Static头文件如下:

#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() {}

编辑:我正在使用visual studio,如果这很重要。

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

void addStatic(Mesh &mesh, Texture &texture, Transform transform) {

按值取一个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*中空闲内存块的悬浮指针。

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


By the way:

Static *statptr = stat.get();
statptr->Draw();

你不需要get()指针。c++的智能指针的行为(几乎)像原始指针,所以

stat->Draw();