【问题标题】:Casting to C string gives strange symbols [duplicate]转换为C字符串会产生奇怪的符号[重复]
【发布时间】:2016-02-14 04:13:17
【问题描述】:

所以我一直在学习 OpenGL,并决定编写一个小的静态函数来从文件加载着色器。这里是:

std::string HM::GetShaderSource(std::string filename)
{
std::string shaderSource = "";
std::string line = "";

std::ifstream shaderFile(filename);
if (shaderFile.is_open())
{
    while (getline(shaderFile, line))
    {
        shaderSource.append(line + "\n");
    }

    shaderFile.close();
}
else std::cout << "Unable to open shader file : " << filename << std::endl;



std::cout << " first output : " << std::endl << (const GLchar *)shaderSource.c_str() << std::endl;

return shaderSource;
}

然后我在我的代码中这样称呼它:

const char * vertexShaderSource = HM::GetShaderSource("VertexShader.txt").c_str();
std::cout << "second output: " << vertexShaderSource << std::endl;
std::cout << "third output: " << HM::GetShaderSource("VertexShader.txt").c_str() << std::endl;

然后打印出来:

first output: ...Normal Shader Code...
second output: second output: ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌7
first output: ...Normal Shader Code...
third output: ...Normal Shader Code...

那么为什么它的行为如此奇怪?为什么当我把它放在一个变量中时它会给出这个奇怪的输出?

【问题讨论】:

  • 考虑关联对象的生命周期。那么,为什么你认为你首先需要一个 C 风格的字符串呢?最后,不要施放。说真的,你隐藏的错误比你用强制转换“修复”的要多。
  • 好吧,回答一下我需要它们的 c 字符串,因为我必须给着色器加载函数一个(或 GLchar *)glShaderSource(vertexShader, 1, **&amp;vertexShaderSource**, NULL);
  • 代码与着色器加载函数无关。它只从文件中读取字符串并打印出来。世界上没有一个理由在这里使用指针。

标签: c++ string char


【解决方案1】:
const char * vertexShaderSource = HM::GetShaderSource("VertexShader.txt").c_str();

将创建一个指向从GetShaderSource 返回的字符串的底层 c 样式字符串的指针。由于您从未捕获该字符串,因此它在表达式的末尾被销毁。所以现在你有一个指向你不再拥有的内存的指针。使用该指针现在是未定义的行为。

有两种方法可以解决此问题。您可以捕获字符串,然后在您的函数中使用它

std::string vertexShaderSource = HM::GetShaderSource("VertexShader.txt");
the_function_you_want_to_call(vertexShaderSource.c_str());

或者,如果您永远不会再次使用该函数,则可以将其作为参数调用。

the_function_you_want_to_call(HM::GetShaderSource("VertexShader.txt").c_str());

【讨论】:

  • 这是最好的解决方法:std::string str = HM::GetShaderSource("VertexShader.txt"); const char * vertexShaderSource = str.c_str(); 还是有更好的方法?
  • @Rokner 这取决于。调用glShaderSource后需要保留字符串吗?
  • 我可以将它用于其他着色器。喜欢:str = GetSource1; glShaderSource(str); str = GetSOurce2; glShaderSource(str); ... 之后我就不需要它了。
  • @Rokner 我更新了我的答案。让我知道这是否适合您。
  • 是的,谢谢,很好。
猜你喜欢
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 2021-04-02
  • 2018-03-08
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多