C++ glShaderSource中的Segfault

C++ glShaderSource中的Segfault,c++,pointers,opengl,C++,Pointers,Opengl,好的,我已经加载了一个glVertex着色器,作为来自hexdump的const char字符串。但是,我从以下代码中得到一个编译器错误,我无法理解为什么它拒绝编译此代码,错误为: main.cpp: In function ‘void loadShaders()’: main.cpp:27:55: error: cannot convert ‘const char (*)[92]’ to ‘const GLchar** {aka const char**}’ in argument passi

好的,我已经加载了一个glVertex着色器,作为来自hexdump的const char字符串。但是,我从以下代码中得到一个编译器错误,我无法理解为什么它拒绝编译此代码,错误为:

main.cpp: In function ‘void loadShaders()’: main.cpp:27:55: error: cannot convert ‘const char (*)[92]’ to ‘const GLchar** {aka const char**}’ in argument passing glShaderSource(vertexShader, 1, &vertex_glsl, NULL); ^ 试试看:

glShaderSource(vertexShader, 1, &vertex_glsl, &vertex_glsl_len);
问题可能只是在这种情况下,它不应该由以null结尾的字符串驱动,而是由大小定义的字符串驱动


字符数组在每一行终止字符串。

虽然C/C++指针和数组在许多上下文中的行为方式相同,但它们并不相同。您在这里遇到的问题,包括初始编译错误和添加类型转换后的崩溃,是这两者不同的一个示例:

  • 应用于数组的
    &
    运算符为您提供数组的地址,该地址是指向存储在数组中的数据的指针。应用运算符产生的实际地址(而不是类型)与数组中第一个元素的地址相同。因此,通过这一声明:

    char s[] = "abc";
    
    以下两种说法:

    &s
    &s[0]
    
    &t
    &t[0]
    
    结果是相同的地址。同样,这两个表达式的类型不同,第一个是指向数组的指针,第二个是指向字符的指针,但地址是相同的

  • 应用于指针变量的
    &
    运算符提供指针变量的地址。跟进同一个例子:

    char s[] = "abc";
    char* t = s;
    
    以下两种说法:

    &s
    &s[0]
    
    &t
    &t[0]
    
    产生不同的地址。第一个是指针变量
    t
    的地址,第二个是指向第一个字符的指针,与上面的
    &s[0]
    相同

glShaderSource()
的第三个参数的类型是
const GLchar**
,这意味着必须传递指针变量的地址。您在第一次尝试中遇到的编译错误是一个严重错误,因为您确实传递了错误类型的值(指向数组的指针)。添加类型转换只会让中断的代码通过编译器,并在运行时导致崩溃

要实现这一点,需要将字符串分配给
const GLchar*
类型的变量,并传递该变量的地址:

const GLchar* vertex_glsl_ptr = vertex_glsl;
glShaderSource(vertexShader, 1, &vertex_glsl_ptr, NULL);

这将在不使用类型转换的情况下编译,并且在运行它时不会崩溃。

您试图为只接受2D列表的函数提供1D列表…@Ben那么我该如何解决这个问题呢。我认为在类型声明中,
[]
等同于
*
。就像在
[]
中一样,当代码运行时,它只是另一个指针。你从哪里得到顶点着色器的源代码?为什么它看起来不像文本,为什么有嵌入的NUL字节?请尝试以下操作:
const char*temp=vertex\u glsl;glShaderSource(顶点着色器,1,&temp,NULL)
@JWWalker我使用
xxd
从一个文件转换而来,这样我就可以将源代码编译到我的程序中。但是,它必须以null结尾,所以我只是使用sed将最后一个字节转换为null。