glShaderSource()上的分段错误

时间:2014-11-23 06:40:09

标签: c++ opengl segmentation-fault shader

char buffer[1024];   

memset(buffer, 0, sizeof(buffer));
FILE *vertexShaderFile = fopen(vertexShaderPath.c_str(), "rb");
fread(buffer, 1, sizeof(buffer) - 1, vertexShaderFile);
fclose(vertexShaderFile);

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, (const char **)&buffer, nullptr);
glCompileShader(vertexShader);

使用此代码,我在调用glShaderSource()时出现分段错误。使用GDB,我确认buffer(着色器代码)的内容正确地以空值终止。除此之外,我还检查了GLEW_ARB_shader_objectsglShaderSource是否已加载。

这可能会发生什么?


经过一些修修补补后,我发现如果我在堆上复制buffer,即从中创建std::string并将glShaderSource()指针传递给它的c_str()返回的指针有效。

现在我更加困惑。


除此之外,即使我只是声明一个char *指向buffer并将其传递进去,它也能正常工作。当你声明一个指向数组的指针而不是一个指向指针的指针时,C ++ 11是否会做一些特殊的事情?

1 个答案:

答案 0 :(得分:2)

您使用的是C语法错误:

char buffer[1024];
...
glShaderSource(..., (const char **)&buffer, ...);

这是指向真实字符串数据的指针。 根据定义,&buffer与此处的buffer相同 - 指向charbuffer的第一个char *的指针,类型为buffer。将其转换为其他内容只会隐藏此处的错误。

此构造原则上不能正常工作。没有显式变量保存该缓冲区的地址,编译器将在编译时直接将对&12345的访问转换为内存位置(在本例中为堆栈)。 与常见的神话相反,数组与C / C ++ 中的指针相同。数组的名称只是求值为第一个对象的指针值,但这不是一回事。您要做的事情在概念上与获取直接值的地址相同:char buffer[1024]; char *pBuffer=buffer; ... glShaderSource(..., &pBuffer, ...); 。你永远不能得到一个不存在的东西的地址。

你当然能做的就是创造一个:

char **

现在,你在内存中有一个指针,它实际上保存了缓冲区的地址。当然,您可以获取该指针变量的地址,获取{{1}}类型的表达式。