1

私が取り組んでいる OpenGL アプリケーションの一部から取られた次のコードがあります。GDB は、 を呼び出すとすぐにコード segfaults を報告しますglfwInit()。奇妙なことに、の値heightを 256 (または少なくともheight512 未満) に変更すると、segfault が消えます。

#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このエラーの原因について困惑しています。値を変更すると segfaultに影響する理由がわかりません。

編集:より多くのコードを投稿しました。幅/高さが 512 の場合でも segfault が発生しますが、256 では問題なく動作します。

4

2 に答える 2

3

スタックに 9437184 バイトのデータを割り当てることになります。9.43メガバイト。これは1 つのスタック フレームで大量のメモリを使用するため、使用している環境でスタック全体に許容される量を超える可能性があります。

正直なところ、正確な問題が何であるかはわかりませんが、高さの値を小さくするとすべてが修正されると述べているため(高さを半分にすると〜4.7 MBになります)、これが問題だと思います。Visual Studioのデフォルトは 1MB であると読んだことがありますが、少なくとも 5MB はスタックサイズとして妥当なようです。これをさらに詳しく調べたい場合は、GCC が提供するデフォルトのスタック サイズを調べるか、segfault が見つかるまでスタック サイズを明示的に設定します (可能な場合)。クイック検索では約8MBと表示されますが、これは正確ではない可能性があります。これが正しいと仮定すると、それを超えることができました。

そのデータをヒープに動的に設定します。これは通常、大量のデータを対象としていますが、スタックは一時/ローカル ストレージを対象としています。

于 2013-04-27T00:59:35.223 に答える