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
(着色器代码)的内容正确地以 null 结尾。除此之外,我还检查了 GLEW_ARB_shader_objects
和 glShaderSource
是否已加载。
这里可能发生了什么?
经过一番修修补补后,我发现如果我在堆上制作一个 buffer
的拷贝,即从中制作一个 std::string
并传递 glShaderSource()
指向其 c_str()
返回的指针的指针,它起作用了。
现在我更糊涂了。
最重要的是,即使我简单地声明一个指向 buffer
的 char *
并将其传入,它也能正常工作。当您声明指向数组的指针与指向指针的指针时,C++11 会做一些特别的事情吗?
最佳答案
您错误地使用了 C 语法:
char buffer[1024];
...
glShaderSource(..., (const char **)&buffer, ...);
这不是指向真实字符串数据的指针。
根据定义,&buffer
与此处的 buffer
相同 - 指向 buffer
中第一个 char
的指针,类型字符 *
。将其转换为其他内容只会隐藏此处的错误。
这个结构原则上是行不通的。没有保存该缓冲区地址的显式变量,编译器将在编译时直接将对 buffer
的访问转换为内存位置(在本例中,在堆栈上)。
与常见的神话相反,数组与 C/C++ 中的指针不同。数组的名称只是评估为指向第一个对象的指针值,但这不是一回事。您要做的在概念上与获取立即值的地址相同:&12345
。您永远无法获得一开始就不存在的地址。
你当然可以做的是创建一个:
char buffer[1024];
char *pBuffer=buffer;
...
glShaderSource(..., &pBuffer, ...);
现在,您在内存中有一个指针,它实际上保存着缓冲区的地址。你当然可以取那个指针变量的地址,得到一个 char **
类型的表达式。
关于c++ - glShaderSource() 上的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27086313/