'C6385 Reading invalid data from 'ss': the readable size is '352' bytes, but '-176' bytes may be read

i was working on an OpenGL project in visual studio and I had two shaders in the same file a fragment shader and vertex shader , before fragment shader I had a line that said #shader fragment and before the vertex shader a line that said #shader vertex, i made a function that could parse and separate the 2 shaders, the function was called called parseshader

note : the reason I had a struct is that I wanted it to output 2 two strings a string containing the vertex shader and a string containing the fragment shader i wanted it to output two strings because I had another function to compile the shader that had two parameters the vertex shader code and the fragment shader code

        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() };
    }

the proplem is that I get a warning at the line where I wrote ss[(int)type] << line << "\n"; that says C6385 Reading invalid data from 'ss': the readable size is '352' bytes, but '-176' bytes may be read.



Solution 1:[1]

C6385 is a buffer overrun warning. It's telling you that you have a possible array indexing problem in your code, which is true!

If you do not succeed in finding the data you want in a line from your file, then you're trying to access ss[-1], which is clearly nonsense. (Each stringstream must be 176 bytes wide in your environment, based on the specific warning text.) You must not do that: -1 is not a valid array index.

In fact, you will be making this error even if you've previously found a good line in the file, because you keep declaring new local variables type instead of assigning to the existing one.


If I understand your code and goal correctly, I suggest the following changes:

  1. Remove shadertype from those inner if statements, to change your declarations into assignments.
  2. Put if (type != shadertype::NONE) before your ss[(int)type] access, possibly accompanied by an assertion if you're not expecting files out-of-pattern.

Also, make your indentation consistent so that your program is more easily readable.


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() };
}

Solution 2:[2]

ASSERT if type is not shadertype::NONE.

Probably that'd give you some hints.

From what I see in your code, there's an execution path, in which it's possible type to still be shadertype::NONE. In that case you're dereferencing bad index.

Solution 3:[3]

You redeclared your type variable

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;

}

should be

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;

}

Solution 4:[4]

what you can do is check if the shader is NOT ShaderType::NONE.

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

Also, to optimize a little bit the memory that the enum class ShaderType occupies you should make it's type char (only since C++ 11) like this:

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

And you also have to change the cast from int to char

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Doncho
Solution 3 john
Solution 4 Alberto Tejera Pais