std::string 和默认移动构造函数导致堆损坏

问题描述 投票:0回答:1

在重构一些代码时,我遇到了堆损坏的问题。

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++ 很有经验,而这整件事真是太奇怪了。我已经进行了多次调试,但没有产生任何结果。

c++ default-constructor heap-corruption move-constructor
1个回答
0
投票

我切换到 MSVC,问题似乎消失了; Address Sanitizer 仍然没有发现任何问题。使用我自己的数组类代替 std::string 和 std::filesystem::path 也可以。

我不知道我是否应该相信自己的发现(也许是 gcc bug?),或者我在切换到 MSVC 后继续赢得堆损坏彩票。

© www.soinside.com 2019 - 2024. All rights reserved.