【问题标题】:Access violation reading location 0x00000000 despite no pointers尽管没有指针,但访问冲突读取位置 0x00000000
【发布时间】:2016-04-03 07:07:19
【问题描述】:

除非我弄错了,否则“访问冲突读取位置 0x00000000”意味着您正在尝试延迟尚未初始化的指针,这就是为什么我被这个错误难住了。下面粘贴的是我的代码,并带有注释,指出 Visual Studio 调试器告诉我发生错误的位置。它让我感到困惑,因为我传递给函数的参数都不是指针。有什么想法吗?

void Mesh::Render(Shader* shader)
{
    glBindVertexArray(m_vao);
    glEnableVertexAttribArray(shader->GetAttributeLocation("position"));
    glVertexAttribPointer(0, 3, GL_FALSE, GL_FALSE, sizeof(Vertex), 0);

    glDrawElements(GL_TRIANGLES, m_size, GL_UNSIGNED_INT, 0); // error here

    glDisableVertexAttribArray(shader->GetAttributeLocation("position"));
    glBindVertexArray(0);
}

m_size 被声明为非指针整数

如果它有帮助,调试器会将我带到一些不可用的源,因此调试器会在反汇编中指向这一行:

001DFEC7  mov         edi,dword ptr [esi]  

我不知道组装,所以我不确定这是否有任何帮助。

编辑

如果有人想知道,我正在绑定使用 VAO 所需的元素数组缓冲区。 Mesh 类的其余部分在下面

Mesh::Mesh()
{
    glGenVertexArrays(1, &m_vao);
    glGenBuffers(1, &m_vbo);
    glGenBuffers(1, &m_ibo);
    m_size = 0;
}

Mesh::~Mesh()
{
    glDeleteVertexArrays(1, &m_vao);
    glDeleteBuffers(1, &m_vbo);
    glDeleteBuffers(1, &m_ibo);
}

void Mesh::AddVertices(Vertex* vertices, int vertSize, int* indices, int indexSize)
{
    m_size = indexSize;

    glBindVertexArray(m_vao);

    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
    glBufferData(GL_ARRAY_BUFFER, vertSize * sizeof(Vertex), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize * sizeof(int), indices, GL_STATIC_DRAW);

}

【问题讨论】:

  • 确定有指针。 this 是一个指针,shader 是一个指针,glVertexAttribPointer 的最后一个参数是一个指针(您已将其设置为零......)
  • 这里使用的 m_vao 和其他变量都是全局的吗?
  • As mentioned in this question(和其他人),您绑定了一个无效缓冲区,该缓冲区仅在调用 glDrawElements 时才被访问。你应该测试你对 OpenGL 函数的所有调用,看看它们中是否有任何失败。其中一个可能已失败,因此您没有有效的缓冲区绑定,但您仍尝试继续渲染。
  • 由于您使用的是顶点数组对象 (m_vao),如果您想使用 glDrawElements(和其他基于索引的渲染调用)进行渲染,它必须绑定一个 GL_ELEMENT_ARRAY_BUFFER。虽然您没有显示设置 VAO 的代码,但这可能是问题所在。尝试使用索引绑定和加载元素数组。
  • @ArifBurhan m_vao 和其他变量是 Mesh 类的成员。 @Cornstalks 好吧,我的断点导致我查看 glDrawElements 并且其他人说我不能使用 0 作为最后一个参数(应该可以正常工作)我更改了它并得到了相同的错误但位置不同,所以我我不知道发生了什么。

标签: c++ pointers visual-c++ access-violation unhandled-exception


【解决方案1】:

这里的其他两个答案只是部分正确。 glDrawElements 期望最后一个参数是指向某些索引的指针。但是,与其他答案的建议相反,如果此参数为 0 (NULL) 也没关系,因为:

glDrawElements [...] 的 indices 参数被解释为以基本机器单位测量的缓冲区对象内的偏移量。

如果你用GL_ELEMENT_ARRAY_BUFFER 打电话给glBindBuffer

如果这是您正在尝试的,则段错误意味着先前对 OpenGL 函数的调用失败并且您没有绑定有效的缓冲区。当您调用glDrawElements 时,它没有可使用的有效缓冲区,因此会出现段错误。 Check every OpenGL function call for success 查找哪个失败了。

【讨论】:

  • 很可能是 OP 没有绑定元素数组缓冲区而不是 glBindBuffer 失败。顶点数组对象 (VAO) 是所有与顶点相关的数据的容器:顶点缓冲区对象 (VBO) 和元素数组,因此您只需执行一次绑定调用,并更新所有缓冲区绑定。跨度>
  • 我以前不知道 glGetError 所以我将把它标记为正确答案,唯一的区别是你认为会导致我的问题的函数。事实证明,实际原因是我错误地将GL_FALSE 放在glVertexAttribPointer 的第三个参数中,而不是按原样放置GL_FLOAT
【解决方案2】:

根据this,最后一个参数是“指向存储索引位置的指针”。

你有一个 0。所以它会尝试取消引用位置 0。

【讨论】:

  • 关于您引用的指针的声明仅在 OpenGL 使用客户端顶点数组时有效。 OP 的代码使用服务器端顶点数组(由对glBindVertexArray 的调用指定),它将最后一个参数的含义更改为绑定元素数组缓冲区的偏移量,而不是指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-28
相关资源
最近更新 更多