'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:
- Remove
shadertypefrom those innerifstatements, to change your declarations into assignments. - Put
if (type != shadertype::NONE)before yourss[(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 |
