Почему вызов метода для shared_ptr в векторе вызывает исключение времени выполнения?

Почему следующий код бросает

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, если это имеет значение.

-3

Решение

Это то, что вы получаете, бросая указатели и ссылки по всему коду и не думая о времени жизни.

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*,

Не уверен насчет других ваших указателей, но вы берете все как ссылку, поэтому, пожалуйста, проверьте, когда они будут уничтожены, другие указатели могут также указывать на свободное место.


Кстати:

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

Вам не нужно get() указатель Умные указатели C ++ ведут себя (почти) как необработанные указатели, поэтому

stat->Draw();

работает.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]