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_objects
和glShaderSource
是否已加载。
这可能会发生什么?
经过一些修修补补后,我发现如果我在堆上复制buffer
,即从中创建std::string
并将glShaderSource()
指针传递给它的c_str()
返回的指针有效。
现在我更加困惑。
除此之外,即使我只是声明一个char *
指向buffer
并将其传递进去,它也能正常工作。当你声明一个指向数组的指针而不是一个指向指针的指针时,C ++ 11是否会做一些特殊的事情?
答案 0 :(得分:2)
您使用的是C语法错误:
char buffer[1024];
...
glShaderSource(..., (const char **)&buffer, ...);
这是不指向真实字符串数据的指针。
根据定义,&buffer
与此处的buffer
相同 - 指向char
中buffer
的第一个char *
的指针,类型为buffer
。将其转换为其他内容只会隐藏此处的错误。
此构造原则上不能正常工作。没有显式变量保存该缓冲区的地址,编译器将在编译时直接将对&12345
的访问转换为内存位置(在本例中为堆栈)。
与常见的神话相反,数组不与C / C ++ 中的指针相同。数组的名称只是求值为第一个对象的指针值,但这不是一回事。您要做的事情在概念上与获取直接值的地址相同:char buffer[1024];
char *pBuffer=buffer;
...
glShaderSource(..., &pBuffer, ...);
。你永远不能得到一个不存在的东西的地址。
你当然能做的就是创造一个:
char **
现在,你在内存中有一个指针,它实际上保存了缓冲区的地址。当然,您可以获取该指针变量的地址,获取{{1}}类型的表达式。