2014-11-23 58 views
0
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_objectsglShaderSource已經加載。glShaderSource()

這裏可能會發生什麼?


一些修修補補之後我發現,如果我做的buffer副本上堆,即由它作出std::string並通過glShaderSource()一個指向其c_str()返回的指針,它的工作原理。

現在我更加困惑。


在此之上,即使我只是宣佈char *指向buffer,並把它傳遞,它的工作原理。當你聲明一個指向數組的指針與指向指針的指針時,C++ 11會做一些特殊的事情嗎?

回答

2

您錯誤地使用C語法:

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

這是不是指針的指針字符串的真正數據。 根據定義,&buffer與此處的buffer相同 - 指向buffer中的第一個char,類型爲char *的指針。將其轉換爲其他內容只會隱藏錯誤。

這個構造原則上不能工作。沒有顯式變量保存該緩衝區的地址,編譯器會在編譯時直接將對buffer的訪問轉換爲內存位置(在本例中爲堆棧)。 與常見的神話相反,陣列是而不是與C/C++中的指針相同。數組的名稱只是計算一個指向第一個對象的指針值,但這不是一回事。你在做的事情在概念上與採用立即值的地址相同:&12345。你永遠不會得到一個不存在的東西的地址。

你當然可以做的就是創建一個:

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

現在,你有內存的指針,其實際持有的緩衝區的地址。你當然可以得到那個指針變量的地址,得到一個帶有char **類型的表達式。

+0

這就是我最終做的,但非常感謝您的詳細解釋! – jmegaffin 2014-11-23 14:59:50