1

我有以下代码,取自我正在处理的 OpenGL 应用程序的一部分。GDB 在调用时立即报告代码段错误glfwInit()。奇怪的是,如果我将值更改height为 256(或至少,任何height< 512 的值),段错误就会消失。

#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 处运行良好。

4

2 回答 2

3

You end up allocating 9437184 bytes of data on the stack. 9.43 MB. This is a lot of memory in one stack frame, and possibly more than your environment allows for the entire stack.

To be honest I'm not sure what the precise issue is, but since you mention a smaller height value fixes everything (cutting height in half gives ~4.7 MB) I think this is the issue. At least, 5MB seems sorta reasonable for stack size though I've read the default for Visual Studio is 1MB. If you want to go deeper into this, discover what the default stack size GCC gives or explicitly set the stack size (assuming you can) until you find a segfault. A quick search says it's around 8MB, though this may not be accurate for you. Assuming this is correct then you managed to exceed it.

Set that data on the heap dynamically. It's normally meant for large amounts of data, while the stack is meant for temporary/local storage.

于 2013-04-27T00:59:35.223 回答
2
于 2013-04-26T20:18:14.223 回答