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

GLFW窗口指针0xCCCCCCCC访问违例问题求助

解决你的GLFW DLL内存访问违例问题

嘿,我一眼就揪出了导致你遇到read access violation. window was 0xCCCCCCCC错误的两个核心问题,咱们一步步来修复:

问题1:返回局部变量地址,直接生成野指针

你在LIB_CreateWindow里定义了栈上的局部变量LIB_Window wind;,函数执行完毕后,栈上的这个变量会被系统回收,内存会被标记成0xCCCCCCCC(这是VC++用来标记已释放栈内存的特殊值)。当你返回&wind;给调用者时,拿到的就是一个指向无效内存的野指针,后续任何访问这个指针的操作都会触发内存错误。

问题2:画蛇添足的二级指针

你的LIB_Window结构体里用了GLFWwindow** window;,但glfwCreateWindow返回的本来就是GLFWwindow*类型的一级指针,强行转成二级指针完全没必要,这会导致后续调用GLFW API时指针类型不匹配,雪上加霜。


修复步骤全解析

1. 先修正结构体的指针类型

把LIB_Window里的二级指针改成一级指针,和GLFW的返回类型匹配:

struct LIB_Window {
 LIB_String title;
 int x;
 int y;
 int width;
 int height;
 LIB_Bool fullscreen;
 GLFWwindow* window; // 改为一级指针
};

2. 用堆内存创建窗口实例

把局部变量换成malloc分配的堆内存,这样函数结束后内存不会被回收:

LIB_Window* LIB_CreateWindow(const LIB_String title, int x, int y, const int width, const int height, const LIB_Bool resizable, const LIB_Bool fullscreen) {
 // 堆内存分配,确保内存持久化
 LIB_Window* wind = (LIB_Window*)malloc(sizeof(LIB_Window));
 if (!wind) {
     glfwTerminate();
     return NULL;
 }

 wind->title = title;
 if (x == LIB_CENTER_POSITION) {
     const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
     x = (mode->width - width) / 2;
 }
 wind->x = x;
 if (y == LIB_CENTER_POSITION) {
     const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
     y = (mode->height - height) / 2;
 }
 wind->y = y;
 wind->width = width;
 wind->height = height;
 wind->fullscreen = fullscreen;

 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
 glfwWindowHint(GLFW_RESIZABLE, resizable);

 // 直接用一级指针接收glfwCreateWindow的返回值
 wind->window = NULL;
 if (fullscreen == 1) {
     wind->window = glfwCreateWindow(width, height, title, glfwGetPrimaryMonitor(), NULL);
 } else {
     wind->window = glfwCreateWindow(width, height, title, NULL, NULL);
 }

 // 窗口创建失败时要释放已分配的内存
 if (!wind->window) {
     glfwTerminate();
     free(wind);
     return NULL;
 }

 glfwSetWindowPos(wind->window, x, y);
 int screen_width, screen_height;
 glfwGetFramebufferSize(wind->window, &screen_width, &screen_height);

 glfwMakeContextCurrent(wind->window);
 glewExperimental = GL_TRUE;
 if (glewInit() != GLEW_OK) {
     glfwDestroyWindow(wind->window);
     free(wind);
     return NULL;
 }

 glViewport(0, 0, screen_width, screen_height);
 glMatrixMode(GL_PROJECTION);
 glPushMatrix();
 glLoadIdentity();
 glMatrixMode(GL_MODELVIEW);
 glEnable(GL_BLEND);
 glEnable(GL_ALPHA_TEST);
 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

 return wind;
}

3. 修正所有GLFW API调用的指针

把所有((GLFWwindow*)window->window)的多余强制转换去掉,直接用window->window就行,比如:

void LIB_SwapWindowBuffers(LIB_Window * window) {
 glfwSwapBuffers(window->window);
}

LIB_Bool LIB_IsWindowOpened(LIB_Window * window) {
 return !glfwWindowShouldClose(window->window);
}

4. 完善窗口销毁函数

原来的LIB_DestroyWindow没有销毁GLFW窗口,要加上glfwDestroyWindow,同时确保内存释放:

void LIB_DestroyWindow(LIB_Window * window) {
 if (window && window->window) {
     glfwDestroyWindow(window->window);
 }
 free(window);
}

额外提醒
  • 一定要记得调用LIB_DestroyWindow来释放堆内存,不然会造成内存泄漏
  • 如果你的DLL和调用程序用了不同的C运行时库(CRT),可能会出现跨模块内存分配/释放的问题,建议在VS项目设置里把CRT统一设为Multi-threaded DLL (/MD)
  • 所有涉及GLFW窗口的操作,最好先检查window->window不为NULL再执行,避免空指针错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:57:18