看过《游戏引擎架构》后我开始对内存的分配问题关注,一直想用内存分配器来管理游戏的内存。前两天发现了有许多第三方内存分配器可以用。最后挑中了nedmalloc,这个库也是ogre所使用的,测试了一下,确实比VS的malloc/free要快不少。

通过写几个简单的函数就可以代替allegro内存分配器,十分方便,又顺便给box2d也换了。

allegro通过调用al_set_memory_interface()来替换内存分配器。然后我把这个函数放到了al_init()后面。一运行,发现很正常,不错。点击窗口的关闭按钮,然后报错了!我就猜想是不是放的位置不对。在设置分配器之前调用了al_init(),那就说明allegro初始化的时候申请的内存用的分配器还是默认的分配器,关闭的时候卸载这些初始化的数据缺用的是nedmalloc的free,这样肯定就报错了。于是我把al_set_memory_interface()放到了al_init()之前。再运行,关闭。完全正常!到这里我以为事情就结束了。

后来在写了若干代码之后发现上面那个关闭时报错的问题又出现了!于是开始找问题,注释了几乎所有代码,问题依旧。最后又单步调试,发现报错是在main()返回之后出现的,才意识到,这个问题出现在静态变量上,接着单步调试,发现问题出在一个String类的身上。这个类封装了allegro的字符串操作函数。(这个类所属的库用c++11封装了allegro所有的对象及其操作,官方也推荐过链接

这时突然才想起来我在一个cpp文件里定义了一个文件内的局部变量,类型正是这个String。这是个静态变量,也就是说它初始化的时候main还没调用,卸载的时候也在main()返回之后了。在我这个程序里就是用默认的malloc  new的它,但最后却用nedfree delete的它,这就出问题了。为了解决这个问题,我在main()返回之前再一次调用al_set_memory_interface()。然后运行,又报错!这次是al_uninstall_system()出错了。

我意识到,这是allegro的初始化和卸载的配对出了问题。我原来一直没有用过al_uninstall_system()这个函数,因为原来查资料说是allegro会自动调用这个函数。之后就是查手册,看源码,终于搞懂了。al_init()其实是个宏,用来代替al_install_system(),用al_init()的话会把al_uninstall_system()注册为main()结束后调用的函数(atexit)。所以就不能再用al_init()来初始化了,然后再手动uninstall。

整理一下思路:就是在al_install_system()设置内存分配器,在al_uninstall_system()后设置回默认的分配器。

下面是代码:

int main()
{
al_set_nedmalloc_memory_interface();
if (!al_install_system(ALLEGRO_VERSION_INT, 0))
{
return 1;
} ... al_uninstall_system();
al_set_memory_interface(0);
return 0;
}

以后要用哪个函数的时候,最好还是先看下它的说明。在这个问题之前我都不知道al_install_system()的存在。

allegro设置内存分配器的一个坑的更多相关文章

  1. 关于pyinstaller打包程序时设置icon时的一个坑

    关于pyinstaller打包程序时设置icon时的一个坑     之前在用pyinstaller打包程序的时候遇到了关于设置图标的一点小问题,无论在后面加--icon 或是-i都出现报错.查了下st ...

  2. 14.6.4 Configuring the Memory Allocator for InnoDB 配置InnoDB 内存分配器

    14.6.4 Configuring the Memory Allocator for InnoDB 配置InnoDB 内存分配器 当InnoDB 被开发时,内存分配提供了操作系统和 run-time ...

  3. 内存分配器 (Memory Allocator)

    对于大多数开发人员而言,系统的内存分配就是一个黑盒子,就是几个API的调用.有你就给我,没有我就想别的办法. 来UC前,我就是这样觉得的.实际深入进去时,才发现这个领域里也是百家争鸣.非常热闹.有操作 ...

  4. Nah Lock: 一个无锁的内存分配器

    概述 我实现了两个完全无锁的内存分配器:_nalloc 和 nalloc.  我用benchmark工具对它们进行了一组综合性测试,并比较了它们的指标值. 与libc(glibc malloc)相比, ...

  5. linux内存管理--伙伴系统和内存分配器

    3.1页框的管理 所有的页框描述符都存放在mem_map数组中. 3.1.1page数据结构 struct page { page_flags_t flags; //标志 atomic_t _coun ...

  6. 使用ffmpeg视频编码过程中踩的一个坑

           今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果:                   ...

  7. 14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器

    14.4.4 Configuring the Memory Allocator for InnoDB InnoDB 配置内存分配器 当InnoDB 被开发, 内分配齐 提供了与操作系统和运行库往往缺乏 ...

  8. CoreCLR源码探索(三) GC内存分配器的内部实现

    在前一篇中我讲解了new是怎么工作的, 但是却一笔跳过了内存分配相关的部分. 在这一篇中我将详细讲解GC内存分配器的内部实现. 在看这一篇之前请必须先看完微软BOTR文档中的"Garbage ...

  9. FDG内存分配器笔记

    FDG: 大规模并行系统中的动态内存分配器由于需要全局同步(记账) ,导致性能急剧下降. 代码解析 1.superblock 类中包含两个变量,两个函数.默认superblock大小为2048 ite ...

随机推荐

  1. JavaScript递归注意事项

    var svg_node = document.getElementById("svgnode") function parents(posnode,selector) { var ...

  2. kali机获取不到ip地址解决

    一.方法一 重启网卡:/etc/init.d/networking restart 重启kali:reboot 二.方法二 更改网络适配器:虚拟机-可移动设备-网络适配器设置-选择“桥接模式:直接连接 ...

  3. 赋值、关系、逻辑运算、if、switch case

    cout << boolalpha将打印输出0转为false,1转为true 逻辑运算符: &&(与)    且      两个条件为真时结果为真 ||(或) 或   两个 ...

  4. JSON 文件的存取

    import json data = {'Tom': {'Weight:': 65, 'Score': 90, 'Height': 170}} # json.dumps 将字典转化为 JSON 编码的 ...

  5. C++版本的UnEscape 解析\uxxxx\uxxxx编码字符

    解析类似于这种Unicode编码格式的字符串 \u5b55\u5987\u88c5\u590f\u88c52018\u65b0\u6b3e\u5bbd\u677e\u77ed\u8896\u4e2d\ ...

  6. 洛谷$P4503\ [CTSC2014]$企鹅$QQ$ 哈希

    正解:哈希 解题报告: 传送门$QwQ$ 直接$O(len)$枚举哪一位,然后把这一位删了重新拼接起来,存桶里查下就成 $over$? 主要的难点大概在卡哈希+卡常$QAQ$ #include< ...

  7. $Poj2956/AcWing116\ The\ Pilots\ Brothers'Refrigerator$ 二进制

    AcWing $Sol$ 假设改变$[x1,y1]$和$[x2,y2]$的状态就可以达到目的.注意到先改变谁对结果是没有影响的!! 所以就可以直接枚举改变状态的结点而不需要注意顺序. $4*4$的矩阵 ...

  8. Linux 文件系统 -- inode 笔记

    什么是 inode inode 的定义:Unix 文件系统中的一种数据结构,用来存储文件的元信息数据   文件在硬盘中的存储是以"块"(block)为单位的,常见的块大小是 4k ...

  9. jsp 知识点总结

    JSP 入门案例(计算器的实现) 对于jsp 学习的一些总结 1.使用Dreamweaver 搭建网页 计算器 第一个数字 符号 + - * / 第二个数字 <form id="for ...

  10. 9.python中sys.argv[]用法说明

    在python中sys.argv[]是用来获取命令行输入的参数的(参数和参数之间空格区分),sys.argv[0]表示代码本身文件路径,所以从参数1开始,表示获取的参数了 举例说明:创建一个程序名为t ...