在重构一些代码时,我遇到了堆损坏的问题。
namespace GPU
{
struct ShaderStage
{
public:
ShaderStage(ShaderStageType, const Path&);
ShaderStage() = default;
[Default copy/move constructors]
ShaderStageType StageType = {};
std::string Source = {};
std::filesystem::path BasePath = {};
};
struct Shader
{
public:
Shader(const Path& v, const Path& f);
Shader() = default;
[Default copy/move constructors]
ShaderStage VertexStage = {};
ShaderStage FragmentStage = {};
};
ShaderStage::ShaderStage(ShaderStageType type, const std::filesystem::path& path) : StageType(type), BasePath(path)
{
Source = [any string, loads file in this case];
};
Shader::Shader(const Path& v, const Path& f) :
VertexStage(ShaderStageType::Vertex, v),
FragmentStage(ShaderStageType::Fragment, f)
{
};
}
namespace GL
{
class Shader final : protected GPU::Shader
{
public:
Shader(gE::Window* window, GPU::Shader&&);
Shader() = default;
};
Shader::Shader(gE::Window* window, GPU::Shader&& INTERNAL_SETTINGS) : GPU::Shader(move(INTERNAL_SETTINGS))
{
[Actually constructs GL::ShaderStage, but I can replicate the issue with just moving GPU::ShaderStage around]
GPU::ShaderStage frag = move(FragmentStage);
GPU::ShaderStage vert = move(VertexStage);
FragmentStage = move(frag);
VertexStage = move(vert);
}
}
这就是我构造对象的方式:
GPU::Shader shaderSettings("Resource/Shader/skybox.vert", "Resource/Shader/skybox.frag");
[GL::Shader _skyboxShader = {}]
_skyboxShader = GL::Shader(window, move(shaderSettings));
[SIGTRAP when _skyboxShader goes out of scope]
放置新作品:
GPU::Shader shaderSettings("Resource/Shader/skybox.vert", "Resource/Shader/skybox.frag");
[GL::Shader _skyboxShader = {}]
_skyboxShader.~Shader();
new(&_skyboxShader) GL::Shader(window, move(shaderSettings));
[No error]
我想我对 C++ 很有经验,而这整件事真是太奇怪了。我已经进行了多次调试,但没有产生任何结果。
我切换到 MSVC,问题似乎消失了; Address Sanitizer 仍然没有发现任何问题。使用我自己的数组类代替 std::string 和 std::filesystem::path 也可以。
我不知道我是否应该相信自己的发现(也许是 gcc bug?),或者我在切换到 MSVC 后继续赢得堆损坏彩票。