You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LWJGL3的stbi_load加载图片时出现EXCEPTION_ACCESS_VIOLATION错误

错误根因分析

你触发的EXCEPTION_ACCESS_VIOLATION是典型的原生代码内存访问越界错误,问题完全出在你对stbi_load的入参使用错误,具体问题如下:

  • 第一个致命错误:IntBuffer分配容量不符合要求。stbi_load要求传入的width、height、channels三个IntBuffer仅需要存储1个int值,你现在分别用IntBuffer.allocate(bi.getWidth())、IntBuffer.allocate(bi.getHeight())、IntBuffer.allocate(GL_RGBA)分配了远大于1的容量,且调用put写入值后没有调用flip()重置缓冲区位置,原生代码读取参数时访问了非法内存直接触发崩溃。
  • 第二个错误:路径格式不匹配且逻辑冗余。你是Windows系统,stbi_load传入的是Unix格式的绝对路径/Users/nottn/...,大概率无法找到对应图片,stbi_load会返回null,后续glTexImage2D传入空指针也会触发崩溃;同时你已经调用stbi_load加载图片,前面用ImageIO读取图片完全是多余操作,传入的filename参数也没有实际用到,硬编码了test.png路径。
  • 第三个错误:纹理上传参数错误。stbi_load返回的是无符号字节数据,你用GL_BYTE作为数据类型会导致颜色异常,严重时也可能触发内存访问问题。
  • 第四个潜在问题:stbi_load分配的原生内存没有调用stbi_image_free释放,会造成原生内存泄漏。

修正后的代码示例

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.stb.STBImage.*;
import static org.lwjgl.system.MemoryStack.*;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;

public class Texture {
    private int id;
    private int width, height;
    
    public Texture(String filename) {
        // 用MemoryStack申请栈内存存int参数,用完自动释放,不需要手动管理
        try (var stack = stackPush()) {
            IntBuffer pWidth = stack.mallocInt(1);
            IntBuffer pHeight = stack.mallocInt(1);
            IntBuffer pChannels = stack.mallocInt(1);
            
            // 优先用相对路径,注意stb默认不支持中文路径,路径不要有中文和空格
            String path = "./sprites/" + filename;
            ByteBuffer data = stbi_load(path, pWidth, pHeight, pChannels, STBI_rgb_alpha);
            if (data == null) {
                throw new RuntimeException("加载纹理失败: " + stbi_failure_reason());
            }
            
            width = pWidth.get(0);
            height = pHeight.get(0);
            
            id = glGenTextures();
            glBindTexture(GL_TEXTURE_2D, id);
            
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            
            // 注意数据类型用GL_UNSIGNED_BYTE
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
            
            // 释放stb申请的原生内存
            stbi_image_free(data);
        }
    }
    
    public void Bind() {
        glBindTexture(GL_TEXTURE_2D, id);
    }
    
    public int getWidth() { return width; }
    public int getHeight() { return height; }
}

内容的提问来源于stack exchange,提问作者ralph367

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:24:04