为什么在向量中的 shared_ptr 上调用方法会引发运行时异常?
Why does calling a method on a shared_ptr in a vector throw a runtime exception?
为什么下面的代码抛出
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() {}
编辑:
如果重要的话,我正在使用 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
returns,本地 Transform
被破坏,你最终会得到一个指向 Transform*
.
中空闲内存块的悬空指针
不确定你的其他指针,但你把所有的东西都作为参考,所以请检查,当它们要被销毁时,其他指针可能也会指向 free'd space。
顺便说一句:
Static *statptr = stat.get();
statptr->Draw();
您不需要 get()
指针。 C++ 的智能指针的行为(几乎)像原始指针,所以
stat->Draw();
有效。
为什么下面的代码抛出
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() {}
编辑: 如果重要的话,我正在使用 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
returns,本地 Transform
被破坏,你最终会得到一个指向 Transform*
.
不确定你的其他指针,但你把所有的东西都作为参考,所以请检查,当它们要被销毁时,其他指针可能也会指向 free'd space。
顺便说一句:
Static *statptr = stat.get();
statptr->Draw();
您不需要 get()
指针。 C++ 的智能指针的行为(几乎)像原始指针,所以
stat->Draw();
有效。