【问题标题】:C6385 Reading invalid data from 'ss': the readable size is '352' bytes, but '-176' bytes may be readC6385 从“ss”读取无效数据:可读大小为“352”字节,但可以读取“-176”字节
【发布时间】:2020-04-06 14:28:48
【问题描述】:

我在 Visual Studio 中处理一个 OpenGL 项目,我在同一个文件中有两个着色器一个片段 着色器和顶点着色器,在片段着色器之前我有一行说#shader片段和之前 顶点着色器一行说#shader vertex,我做了一个可以解析和分离2个着色器的函数,这个函数是 叫叫parseshader

注意:我有一个结构的原因是我希望它输出 2 两个字符串,一个包含顶点着色器的字符串和一个包含片段着色器的字符串 我希望它输出两个字符串,因为我有另一个函数来编译具有两个参数的着色器,即顶点着色器代码和片段着色器代码

        struct shaderProgramSource
    {
        std::string VertexSource;
        std::string FragmentSource;
    };

    static shaderProgramSource parseShader(const std::string& filepath) {  
        enum class shadertype{
        NONE = -1 ,VERTEX = 0 ,FRAGMENT = 1
    };  
std::ifstream stream(filepath);
std::stringstream ss[2];
shadertype type = shadertype::NONE;
std::string line;
while (getline(stream, line))
{
    if (line.find("#shader") != std::string::npos)
    {
        if (line.find("vertex") != std::string::npos)
            shadertype type = shadertype::VERTEX;
        else if(line.find("fragment") != std::string::npos)
            shadertype type = shadertype::FRAGMENT;

    }
 else
        ss[(int)type] << line << "\n";
}

return { ss[0].str(),ss[1].str() };
    }

问题是我在写 ss[(int)type] C6385 从“ss”读取无效数据:可读大小为“352”字节,但可以读取“-176”字节。

【问题讨论】:

    标签: c++ visual-c++


    【解决方案1】:

    C6385 is a buffer overrun warning。它告诉您您的代码中可能存在数组索引问题,这是真的!

    如果您没有成功从文件的一行中找到您想要的数据,那么您正在尝试访问ss[-1],这显然是无稽之谈。 (根据具体的警告文本,您的环境中每个 stringstream 必须为 176 字节宽。)您不能这样做:-1 不是有效的数组索引。

    事实上,即使您之前在文件中找到了正确的行,您也会犯此错误,因为您一直在声明新的局部变量 type,而不是分配给现有的变量。


    如果我正确理解您的代码和目标,我建议进行以下更改:

    1. 从那些内部 if 语句中删除 shadertype,将您的声明更改为赋值。
    2. if (type != shadertype::NONE) 放在您的 ss[(int)type] 访问之前,如果您不期望文件不符合模式,可能会伴随一个断言。

    另外,让你的缩进保持一致,这样你的程序更容易阅读。


    struct shaderProgramSource
    {
        std::string VertexSource;
        std::string FragmentSource;
    };
    
    static shaderProgramSource parseShader(const std::string& filepath)
    {
        enum class shadertype
        {
            NONE     = -1,
            VERTEX   = 0,
            FRAGMENT = 1
        };  
    
        std::ifstream stream(filepath);
        std::stringstream ss[2];
        shadertype type = shadertype::NONE;
    
        std::string line;
        while (getline(stream, line))
        {
            if (line.find("#shader") != std::string::npos)
            {
                if (line.find("vertex") != std::string::npos)
                    type = shadertype::VERTEX;
                else if(line.find("fragment") != std::string::npos)
                    type = shadertype::FRAGMENT;
            }
            else if (type != shadertype::NONE)
            {
                ss[(int)type] << line << "\n";
            }
            else
            {
                // Got non-introductory line out of sequence! Don't know
                // what type to use! Consider asserting, or throwing an
                // exception, or something, depending on how defensive you
                // want to be with respect to the input file format.
            }
        }
    
        return { ss[0].str(), ss[1].str() };
    }
    

    【讨论】:

    • @AbodiHagag 尝试访问ss[-1]
    【解决方案2】:

    如果类型不是 shadertype::NONE,则断言。

    这可能会给你一些提示。

    根据我在您的代码中看到的,有一个执行路径,其中的类型可能仍然是 shadertype::NONE。在这种情况下,您将取消引用错误的索引。

    【讨论】:

    • 它是shadertype::NONE所有 执行路径到达ss[(int)type]
    【解决方案3】:

    你重新声明了你的类型变量

    if (line.find("#shader") != std::string::npos)
    {
        if (line.find("vertex") != std::string::npos)
            shadertype type = shadertype::VERTEX;
        else if(line.find("fragment") != std::string::npos)
            shadertype type = shadertype::FRAGMENT;
    
    }
    

    应该是

    if (line.find("#shader") != std::string::npos)
    {
        if (line.find("vertex") != std::string::npos)
            type = shadertype::VERTEX;
        else if(line.find("fragment") != std::string::npos)
            type = shadertype::FRAGMENT;
    
    }
    

    【讨论】:

      【解决方案4】:

      您可以做的是检查着色器是否为 NOT ShaderType::NONE。

      if(type != ShaderType::NONE){
          ss[(int)type] << line << '\n';
      }
      

      此外,为了优化枚举类 ShaderType 占用的内存,您应该将其设为 char 类型(仅从 C++ 11 开始),如下所示:

      enum class ShaderType : char {
          NONE = -1, VERTEX = 0, FRAGMENT = 1
      };
      

      您还必须将演员表从 int 更改为 char

      if (type != ShaderType::NONE) {
          ss[(char)type] << line << '\n';
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-08
        • 2019-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-05
        相关资源
        最近更新 更多