Reputation: 1172
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);
Using this code, I get a segmentation fault upon my call to glShaderSource()
. Using GDB, I've confirmed that the contents of buffer
(the shader code) is properly null-terminated. On top of this, I've checked that both GLEW_ARB_shader_objects
and glShaderSource
have been loaded.
What could be going on here?
After some tinkering I've discovered that if I make a copy of buffer
on the heap, i.e. by making a std::string
from it and passing glShaderSource()
a pointer to the pointer returned by its c_str()
, it works.
Now I'm even more confused.
On top of this, even if I simply declare a char *
pointing to buffer
and pass that in, it works. Does C++11 do something special when you declare a pointer to an array vs. a pointer to a pointer?
Upvotes: 1
Views: 1072
Reputation: 45362
You are using the C syntax incorrectly:
char buffer[1024];
...
glShaderSource(..., (const char **)&buffer, ...);
This is not a pointer to a pointer to the real string data.
By definition, &buffer
is the same as buffer
here - a pointer to the first char
in buffer
, of type char *
. Casting that to something else only conceals the error here.
This construct can not work in principle. There is no explicit variable which holds the address of that buffer, the compiler will directly transform accesses to buffer
to the memory locations (on the stack, in this case) at compile time.
Contrary to the common myth, arrays are not the same as pointers in C/C++. The name of an array just evaluates to a pointer value to the first object, but that is not the same thing. What you are tring to do is conceptually the same as taking the address of an immediate value: &12345
. You can never get an address of something which does not exist in the first place.
What you of course can do is create one:
char buffer[1024];
char *pBuffer=buffer;
...
glShaderSource(..., &pBuffer, ...);
Now, you have a pointer in memory which actually holds the address of your buffer. And you can of course take the address of that pointer variable, getting an expression with char **
type.
Upvotes: 6