2013-04-26 72 views
1

我有以下代码,取自我正在开发的OpenGL应用程序的一部分。当调用glfwInit()时,GDB报告代码立即发生段错误。奇怪的是,如果我将height的值更改为256(或至少如此,则任何事情都会如此),segfault消失。SegForm与GLFW和GLEW

#include <GL/glew.h> 
#include <GL/glfw.h> 

static const size_t width = 512; 
static const size_t height = 512; 

int main(int argc, char const *argv[]) 
{ 
    glfwInit(); 
    glfwOpenWindow(1080, 720, 8, 8, 8, 0, 32, 0, GLFW_WINDOW); 
    glewInit(); 

    float heightmap[width * height * 3]; 
    for (size_t i = 0, ix = 0; i < width; i++) { 
     for (size_t j = 0; j < height; j++) { 
      float noise = 0.0f; 
      heightmap[ix++] = (float)i; 
      heightmap[ix++] = noise; 
      heightmap[ix++] = (float)j; 
     } 
    } 

    const int numIndices = (width - 1) * (height - 1) * 6;timd 
    GLuint indices[numIndices]; 
    for (size_t i = 0, ix = 0; i < width - 1; i++) { 
     for (size_t j = 0; j < height - 1; j++) { 
      indices[ix++] = (i + 0) + (j + 0) * width; 
      indices[ix++] = (i + 1) + (j + 0) * width; 
      indices[ix++] = (i + 0) + (j + 1) * width; 
      indices[ix++] = (i + 0) + (j + 1) * width; 
      indices[ix++] = (i + 1) + (j + 0) * width; 
      indices[ix++] = (i + 1) + (j + 1) * width; 
     } 
    } 

    GLuint vbo; 
    glGenBuffers(1, &vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 
    glBufferData(GL_ARRAY_BUFFER, width * height * 3 * sizeof(float), heightmap, GL_STATIC_DRAW); 

    GLuint ebo; 
    glGenBuffers(1, &ebo); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(GLuint), indices, GL_STATIC_DRAW); 

    do { 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glBindBuffer(GL_ARRAY_BUFFER, vbo); 
     glEnableVertexAttribArray(0); 
     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
     glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, NULL); 
     glfwSwapBuffers(); 
    } while(glfwGetKey(GLFW_KEY_ESC) != GLFW_PRESS); 

    glDeleteBuffers(1, &vbo); 
    glDeleteBuffers(1, &ebo); 

    glfwCloseWindow(); 
    glfwTerminate(); 
    return 0; 
} 

从GDB回溯显示

#0 0x00000000004009d7 in main (argc=<error reading variable: Cannot access memory at address 0x7fffff6fe41c>, argv=<error reading variable: Cannot access memory at address 0x7fffff6fe410>) at segfault.c:8 

我与gcc -g -o segfault segfault.c -lGL -lGLEW -lglfw编译。

我不明白为什么改变height的值会影响段错误。

编辑:发布了更多的代码。段错误仍与宽度/高度发生在512,但在256

+1

好吧,'512 * 512 * 3',再乘以3,每个浮点4个字节,为您提供3145728个字节。或3.14 MB(PI ?!)。这也是唯一的一个数组,你以后也会创建另一个索引数组。你确定你没有完全消除你的堆栈,可能堆吗?也就是说,尝试在堆上动态分配这些数组。应该有点安全。噢,也许检查GCC的标准堆栈大小(我不使用GCC,所以我不能在那里帮忙)?我认为堆栈/堆损坏是一个问题。 – Hydronium 2013-04-26 20:00:38

+0

'4每个浮动4个字节'*完全忘了解决这个问题。 – Hydronium 2013-04-26 20:15:08

+0

@Hydronium:我在调用'glBufferData()'时犯了一个错误,但你在堆上分配的建议解决了我的问题。随意添加一个答案,我会接受它。 – cdk 2013-04-26 23:56:23

回答

2

您最终在堆栈上分配了9437184个字节的数据。 9.43 MB。这是很多内存在一个堆栈帧,并可能超过您的环境允许整个堆栈。

老实说,我不确定精确问题是什么,但是因为你提到一个较小的高度值可以修复所有东西(切割高度减半〜4.7MB),我认为这是问题所在。至少,5MB对于堆栈大小似乎是合理的,虽然我读过the default for Visual Studio is 1MB。如果你想更深入地了解,发现默认堆栈大小GCC给出或明确设置堆栈大小(假设你可以),直到你找到段错误。一个快速搜索说它是围绕8MB,虽然这可能不准确。假设这是正确的,那么你设法超过了它。

动态地在堆上设置数据。它通常意味着大量数据,而堆栈则用于临时/本地存储。

+3

我邀请了解堆栈,堆和GCC之间关系的人员,以扩展此答案。 – Hydronium 2013-04-27 01:00:37

2

运行正常你没有用数据初始化heightmap

float heightmap[width * height * 3]; 
/* ... */ 
glBufferDataARB(GL_ARRAY_BUFFER, sizeof(heightmap), heightmap, GL_STATIC_DRAW); 

如果你想要做的是初始化OpenGL的缓冲区对象是什么,你可以简单地传递一个空指针。

BTW:所有glBuffer…一直核自从OpenGL的1.4,即你不应该使用ARB扩展,但可以放心地使用核心功能,即使是在最古老的实现,你会发现这几天(甚至适用于我的老式的基于GeForce2的古董电脑)。