看过《游戏引擎架构》后我开始对内存的分配问题关注,一直想用内存分配器来管理游戏的内存。前两天发现了有许多第三方内存分配器可以用。最后挑中了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. 2018-11-9-win2d-CanvasCommandList-使用方法

    title author date CreateTime categories win2d CanvasCommandList 使用方法 lindexi 2018-11-9 20:8:4 +0800 ...

  2. 洛谷——P1111修复公路(并查集)

    题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...

  3. Linux网络文件共享服务之FTP

    一.FTP介绍 ftp(File Transfer Protocol)是早期的三个应用级协议之一,基于C/S结构,双通道协议,数据和命令连接,数据传输格式默认是二进制,当然也支持文件方式传输.默认情况 ...

  4. F#周报2019年第51&52期

    新闻 介绍DataFrame 介绍System.Threading.Channels ConfigureAwait常见问题 第三次年度C#降临节 .NET会议--2020年1月14日 如何找到F#的工 ...

  5. HashMap 原理解析

    HashMap是由数组加链表的结合体.如下图: 图中可以看出HashMap底层就是一个数组结构,每个数组中又存储着链表(链表的引用) JDK1.6实现hashmap的方式是采用位桶(数组)+链表的方式 ...

  6. JSON 文件的存取

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

  7. $CH5105\ Cookies$ 线性$DP+$贪心

    CH 是很有趣的一道题 : ) Sol 第一反应就是f[i][j]表示前i个小朋友分j块饼干的最小怨气值 但是一个孩子所产生的怨气值并不固定,它与其他孩子获得饼干的情况有关 这里可以用到一个贪心,就是 ...

  8. Java迭代器源码解析

    private class Itr implements Iterator<E> { int cursor; // 调用next方法返回的元素的索引 int lastRet = -1; / ...

  9. 手把手带你了解消息中间件(2)——RabbitMQ

    RabbitMQ官网: http://www.rabbitmq.com/ Erlang官网:https://www.erlang.org 友情提示:RabbitMQ基于Erlang语言开发的,要想使用 ...

  10. less实现if else

    less没有我们平常使用的if,else条件判断,而是用when来实现这种用法 1.比如我们要设置宽度 宽度可以百分比,也可以是像素,当是百分比时做对应处理,当是px时做另一种处理,这时候就需要用wh ...