使用Bullet Physics与Texture时malloc()无效尺寸错误排查修复
定位与修复
malloc(): invalid size (unsorted)内存错误 1. 排查新增模块的内存问题
TextRenderer模块
- 检查是否存在非法内存分配参数:比如计算字符纹理缓冲区、字体数据存储大小的时候,出现负数或超大值,导致调用
malloc()传入无效size。比如未正确初始化字体数据,导致字符宽高为负数,后续传给纹理加载的内存分配就会触发错误。 - 确认是否意外篡改了TextureLoader的全局/静态变量:比如TextureLoader维护的纹理缓存链表、内存池指针被TextRenderer的越界写入破坏,导致加载
globe.jpg时malloc参数异常。
敌人循环逻辑
- 检查是否存在重复释放内存、野指针写入:比如创建敌人时重复分配纹理资源,销毁时未置空指针,破坏了堆结构。堆一旦损坏,后续任何malloc调用(包括TextureLoader加载纹理)都可能触发错误。
- 验证是否有数组越界操作:遍历敌人列表时超出容器长度,写入了TextureLoader使用的内存区域,篡改了malloc的内部管理结构。
2. 针对性修复方案
修复TextureLoader关联问题
- 给
globe.jpg加载代码加边界校验:在调用malloc分配纹理像素缓冲区前,强制检查图像宽高是否为正,异常则直接报错返回,避免传入无效size。示例代码:
int width, height; unsigned char* data = stbi_load("/root/SourceCodes/CPP/Assets/Textures/globe.jpg", &width, &height, NULL, 4); if (width <= 0 || height <= 0 || !data) { fprintf(stderr, "Invalid image data for globe.jpg\n"); return 0; } void* buffer = malloc(width * height * 4); // 此时参数合法
- 检查TextureLoader的内存释放逻辑:确保旧纹理内存被正确释放,没有double free导致堆结构损坏。
修复新增模块问题
- 修正TextRenderer的内存计算:使用字体数据前先校验字体是否初始化完成,字符UV坐标、纹理尺寸计算必须基于合法正数。如果用FreeType库,确保
FT_GlyphSlot的bitmap.width和bitmap.rows为正再分配内存。 - 给敌人循环加边界校验:遍历敌人容器(比如vector、数组)时,用容器的
size()而非硬编码值作为循环上限;销毁敌人时将对象指针置空,避免后续野指针操作。
3. 快速调试技巧
- 用
valgrind运行程序:执行valgrind --leak-check=full ./your_game,它能精准定位触发堆损坏的具体代码行,不管是TextRenderer还是敌人循环的非法操作都能被捕获。 - 启用编译器内存检测:GCC编译时添加
-fsanitize=address参数,运行时会直接报错到内存越界/堆损坏的代码位置。
内容的提问来源于stack exchange,提问作者Freya the Goddess
相关产品推荐
相关产品推荐

