【问题标题】:Segfault with GLFW and GLEWGLFW 和 GLEW 的段错误
【发布时间】:2013-04-26 18:34:34
【问题描述】:

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

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

【问题讨论】:

  • 嗯,512 * 512 * 3,再次乘以 3,每个浮点数为 4 个字节,得到 3145728 个字节。或 3.14 MB(PI?!)。这也只是一个数组,稍后您还将创建另一个索引数组。你确定你没有完全消除你的堆栈和可能的堆吗?即,尝试在堆上动态分配这些数组。应该安全一点。哦,也许检查一下 GCC 的标准堆栈大小是多少(我不使用 GCC,所以我帮不上什么忙)?我可能完全不认为堆栈/堆损坏是一个问题。
  • by 4 for 4 bytes per float* 完全忘了解决这个问题。
  • @Hydronium:我在调用glBufferData() 时犯了一个错误,但是您在堆上分配的建议解决了我的问题。随意添加答案,我会接受。

标签: c opengl segmentation-fault glew glfw


【解决方案1】:

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

老实说,我不确定 精确 的问题是什么,但是由于您提到较小的高度值可以解决所有问题(将高度减半大约为 4.7 MB)我认为这就是问题所在.至少,虽然我读过the default for Visual Studio is 1MB,但对于堆栈大小来说,5MB 似乎是合理的。如果您想更深入地了解这一点,请发现 GCC 给出的默认堆栈大小或显式设置堆栈大小(假设可以),直到找到段错误。快速搜索表明它在8MB 附近,尽管这对您来说可能不准确。假设这是正确的,那么您设法超过了它。

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

【讨论】:

  • 我邀请任何对堆栈、堆和 GCC 之间的关系有更多了解的人来扩展这个答案。
【解决方案2】:

你没有用数据初始化heightmap

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

如果您只想初始化 OpenGL 缓冲区对象,您可以简单地传递一个空指针。

顺便说一句:自 OpenGL-1.4 以来,所有的 glBuffer… 都是核心,也就是说,你不应该使用 ARB 扩展,但可以安全地使用核心功能,即使在你现在发现的最古老的实现上也是如此(它甚至适用于我基于 GeForce2 的老式计算机)。

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多